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

              List<Element> floors = new List<Element>();
              if( !Util.GetSelectedElementsOrAll(
            floors, uidoc, typeof( Floor ) ) )
              {
            Selection sel = uidoc.Selection;
            message = ( 0 < sel.GetElementIds().Count )
              ? "Please select some floor elements."
              : "No floor elements found.";
            return Result.Failed;
              }

              List<Face> faces = new List<Face>();
              Options opt = app.Application.Create.NewGeometryOptions();

              foreach( Floor floor in floors )
              {
            GeometryElement geo = floor.get_Geometry( opt );
            //GeometryObjectArray objects = geo.Objects; // 2012
            //foreach( GeometryObject obj in objects ) // 2012
            foreach( GeometryObject obj in geo ) // 2013
            {
              Solid solid = obj as Solid;
              if( solid != null )
              {
            GetSideFaces( faces, solid );
              }
            }
              }

              int n = faces.Count;

              Debug.Print(
            "{0} side face{1} found.",
            n, Util.PluralSuffix( n ) );

              using ( Transaction t = new Transaction( doc ) )
              {
            t.Start( "Draw Face Triangle Normals" );
            Creator creator = new Creator( doc );
            foreach ( Face f in faces )
            {
              creator.DrawFaceTriangleNormals( f );
            }
            t.Commit();
              }
              return Result.Succeeded;
        }
        static Transform _t = Transform.CreateTranslation( _offset ); // 2014

        #endregion Fields

        #region Methods

        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;

              List<Element> walls = new List<Element>();
              if( !Util.GetSelectedElementsOrAll(
            walls, uidoc, typeof( Wall ) ) )
              {
            Selection sel = uidoc.Selection;
            //message = ( 0 < sel.Elements.Size ) // 2014
            message = ( 0 < sel.GetElementIds().Count ) // 2015
              ? "Please select some wall elements."
              : "No wall elements found.";
            return Result.Failed;
              }

              using( Transaction tx = new Transaction( doc ) )
              {
            tx.Start( "Create model curve copies of analytical model curves" );

            Creator creator = new Creator( doc );

            foreach( Wall wall in walls )
            {
              AnalyticalModel am = wall.GetAnalyticalModel();

              foreach( AnalyticalCurveType ct in _curveTypes )
              {
            IList<Curve> curves = am.GetCurves( ct );

            int n = curves.Count;

            Debug.Print( "{0} {1} curve{2}.",
              n, ct, Util.PluralSuffix( n ) );

            foreach( Curve curve in curves )
            {
              //creator.CreateModelCurve( curve.get_Transformed( _t ) ); // 2013

              creator.CreateModelCurve( curve.CreateTransformed( _t ) ); // 2014
            }
              }
            }
            tx.Commit();
              }
              return Result.Succeeded;
        }
        public Result Execute(
            ExternalCommandData commandData,
            ref string message,
            ElementSet elements)
        {
            UIApplication app = commandData.Application;
              UIDocument uidoc = app.ActiveUIDocument;
              Document doc = uidoc.Document;

              FamilyInstance beam = Util.SelectSingleElementOfType(
            uidoc, typeof( FamilyInstance ), "a beam", false ) as FamilyInstance;

              BuiltInCategory bic
            = BuiltInCategory.OST_StructuralFraming;

              if( null == beam
            || null == beam.Category
            || !beam.Category.Id.IntegerValue.Equals( (int) bic ) )
              {
            message = "Please select a single beam element.";
              }
              else
              {
            LocationCurve curve
              = beam.Location as LocationCurve;

            if( null == curve )
            {
              message = "No curve available";
              return Result.Failed;
            }

            XYZ p = curve.Curve.GetEndPoint( 0 );
            XYZ q = curve.Curve.GetEndPoint( 1 );
            XYZ v = 0.1 * (q - p);
            p = p - v;
            q = q + v;

            Creator creator = new Creator( doc );
            creator.CreateModelLine( p, q );
              }
              return Result.Succeeded;
        }
        /// <summary>
        /// Improved implementation by Alexander Ignatovich
        /// supporting curved wall with curved window,
        /// second attempt, published April 10, 2015:
        /// </summary>
        public Result Execute3(
            ExternalCommandData commandData,
            ref string message,
            ElementSet elements)
        {
            UIApplication uiapp = commandData.Application;
            UIDocument    uidoc = uiapp.ActiveUIDocument;
            Application   app   = uiapp.Application;
            Document      doc   = uidoc.Document;
            View          view  = doc.ActiveView;

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

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

            Reference r = uidoc.Selection.PickObject(
                ObjectType.Element, "Select a wall");

            Element e = uidoc.Document.GetElement(r);

            Creator creator = new Creator(doc);

            Wall wall = e as Wall;

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

            using (Transaction tx = new Transaction(doc))
            {
                tx.Start("Wall Profile");

                // Get the external wall face for the profile
                // a little bit simpler than in the last
                // implementation in Execute2.

                Reference sideFaceReference
                    = HostObjectUtils.GetSideFaces(
                          wall, ShellLayerType.Exterior)
                      .First();

                Face face = wall.GetGeometryObjectFromReference(
                    sideFaceReference) as Face;

                // The plane and normal of the wall external face.

                XYZ       normal  = wall.Orientation.Normalize();
                Transform ftx     = face.ComputeDerivatives(UV.Zero);
                XYZ       forigin = ftx.Origin;
                XYZ       fnormal = ftx.BasisZ;

                Debug.Print(
                    "wall orientation {0}, face origin {1}, face normal {2}",
                    Util.PointString(normal),
                    Util.PointString(forigin),
                    Util.PointString(fnormal));

                // Offset distance.

                double d = 5;

                // Offset curve copies for visibility.

                XYZ       voffset = d * normal;
                Transform offset  = Transform.CreateTranslation(
                    voffset);

                // If the curve loop direction is counter-
                // clockwise, change its color to RED.

                Color colorRed = new Color(255, 0, 0);

                // Get edge loops as curve loops.

                IList <CurveLoop> curveLoops
                    = face.GetEdgesAsCurveLoops();

                foreach (var curveLoop in curveLoops)
                {
                    //CurveLoop curveLoopOffset = CurveLoop.CreateViaOffset(
                    //  curveLoop, d, normal );

                    CurveArray curves = creapp.NewCurveArray();

                    foreach (Curve curve in curveLoop)
                    {
                        curves.Append(curve.CreateTransformed(
                                          offset));
                    }

                    var isCounterClockwize = curveLoop
                                             .IsCounterclockwise(normal);

                    // Create model lines for an curve loop if it is made

                    Curve wallCurve = ((LocationCurve)wall.Location).Curve;

                    if (wallCurve is Line)
                    {
                        //Plane plane = creapp.NewPlane( curves ); // 2016

                        //Plane plane = curveLoopOffset.GetPlane(); // 2017

                        Plane plane = Plane.CreateByNormalAndOrigin( // 2019
                            normal, forigin + voffset);

                        Debug.Print(
                            "plane origin {0}, plane normal {1}",
                            Util.PointString(plane.Origin),
                            Util.PointString(plane.Normal));

                        SketchPlane sketchPlane
                            = SketchPlane.Create(doc, plane);

                        ModelCurveArray curveElements = credoc
                                                        .NewModelCurveArray(curves, sketchPlane);

                        if (isCounterClockwize)
                        {
                            SetModelCurvesColor(curveElements,
                                                view, colorRed);
                        }
                    }
                    else
                    {
                        foreach (var curve in curves.Cast <Curve>())
                        {
                            var curveElements = creator.CreateModelCurves(curve);
                            if (isCounterClockwize)
                            {
                                SetModelCurvesColor(curveElements, view, colorRed);
                            }
                        }
                    }
                }
                tx.Commit();
            }
            return(Result.Succeeded);
        }
            Transform.CreateTranslation(_offset); // 2014
#endif // CREATE_MODEL_CURVES_FOR_TOP_FACE_EDGES

        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;

            Options opt = app.Create.NewGeometryOptions();

            XyzEqualityComparer comparer
                = new XyzEqualityComparer(1e-6);

#if CREATE_MODEL_CURVES_FOR_TOP_FACE_EDGES
            Creator creator = new Creator(doc);

            Transaction t = new Transaction(doc);

            t.Start("Create model curve copies of top face edges");
#endif // CREATE_MODEL_CURVES_FOR_TOP_FACE_EDGES

            IList <Face> topFaces = new List <Face>();

            int n;
            int nWalls = 0;

            //foreach( Element e in uidoc.Selection.Elements ) // 2014

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

                Wall wall = e as Wall;

                if (null == wall)
                {
                    Debug.Print("Skipped "
                                + Util.ElementDescription(e));
                    continue;
                }

                // Get the side faces

                IList <Reference> sideFaces
                    = HostObjectUtils.GetSideFaces(wall,
                                                   ShellLayerType.Exterior);

                // Access the first side face

                Element e2 = doc.GetElement(sideFaces[0]);

                Debug.Assert(e2.Id.Equals(e.Id),
                             "expected side face element to be the wall itself");

                Face face = e2.GetGeometryObjectFromReference(
                    sideFaces[0]) as Face;

                if (null == face)
                {
                    Debug.Print("No side face found for "
                                + Util.ElementDescription(e));
                    continue;
                }

                // When there are opening such as doors or
                // windows in the wall, we need to find the
                // outer loop.
                // For one possible approach to extract the
                // outermost loop, please refer to
                // http://thebuildingcoder.typepad.com/blog/2008/12/2d-polygon-areas-and-outer-loop.html

                // Determine the outer loop of the side face
                // by finding the polygon with the largest area

                XYZ       normal;
                double    area, dist, maxArea = 0;
                EdgeArray outerLoop = null;

                foreach (EdgeArray ea in face.EdgeLoops)
                {
                    if (CmdWallProfileArea.GetPolygonPlane(
                            ea.GetPolygon(), out normal, out dist, out area) &&
                        Math.Abs(area) > Math.Abs(maxArea))
                    {
                        maxArea   = area;
                        outerLoop = ea;
                    }
                }

                n = 0;

#if GET_FACES_FROM_OUTER_LOOP
                // With the outermost loop, calculate the top faces

                foreach (Edge edge in outerLoop)
                {
                    // For each edge, get the neighbouring
                    // face and check its normal

                    for (int i = 0; i < 2; ++i)
                    {
                        PlanarFace pf = edge.get_Face(i)
                                        as PlanarFace;

                        if (null == pf)
                        {
                            Debug.Print("Skipped non-planar face on "
                                        + Util.ElementDescription(e));
                            continue;
                        }

                        if (Util.PointsUpwards(pf.Normal, 0.9))
                        {
                            if (topFaces.Contains(pf))
                            {
                                Debug.Print("Duplicate face on "
                                            + Util.ElementDescription(e));
                            }
                            else
                            {
                                topFaces.Add(pf);
                                ++n;
                            }
                        }
                    }
                }
#endif // GET_FACES_FROM_OUTER_LOOP

                List <XYZ> sideVertices = outerLoop.GetPolygon();

                // Go over all the faces of the wall and
                // determine which ones fulfill the following
                // two criteria: (i) planar face pointing
                // upwards, and (ii) neighbour of the side
                // face outer loop.

                Solid solid = wall.get_Geometry(opt)
                              .OfType <Solid>()
                              .First <Solid>(sol => null != sol);

                foreach (Face f in solid.Faces)
                {
                    if (IsTopFace(f))
                    {
                        IList <XYZ> faceVertices
                            = f.Triangulate().Vertices;

                        //if( sideVertices.Exists( v
                        //  => faceVertices.Contains<XYZ>( v, comparer ) ) )
                        //{
                        //  topFaces.Add( f );
                        //  ++n;
                        //}

                        foreach (XYZ v in faceVertices)
                        {
                            if (sideVertices.Contains <XYZ>(
                                    v, comparer))
                            {
                                topFaces.Add(f);
                                ++n;

#if CREATE_MODEL_CURVES_FOR_TOP_FACE_EDGES
                                // Display face for debugging purposes

                                foreach (EdgeArray ea in f.EdgeLoops)
                                {
                                    IEnumerable <Curve> curves
                                        = ea.Cast <Edge>()
                                          .Select <Edge, Curve>(
                                              x => x.AsCurve());

                                    foreach (Curve curve in curves)
                                    {
                                        //creator.CreateModelCurve( curve.get_Transformed( _t ) ); // 2013
                                        creator.CreateModelCurve(curve.CreateTransformed(_t)); // 2014
                                    }
                                }
#endif // CREATE_MODEL_CURVES_FOR_TOP_FACE_EDGES

                                break;
                            }
                        }
                    }
                }

                Debug.Print(string.Format(
                                "{0} top face{1} found on {2} ({3})",
                                n, Util.PluralSuffix(n),
                                Util.ElementDescription(e)),
                            nWalls++);
            }

#if CREATE_MODEL_CURVES_FOR_TOP_FACE_EDGES
            t.Commit();
#endif // CREATE_MODEL_CURVES_FOR_TOP_FACE_EDGES

            string s = string.Format(
                "{0} wall{1} successfully processed",
                nWalls, Util.PluralSuffix(nWalls));

            n = topFaces.Count;

            TaskDialog.Show("Wall Top Faces",
                            string.Format(
                                "{0} with {1} top face{2}.",
                                s, n, Util.PluralSuffix(n)));

            return(Result.Succeeded);
        }
        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;

              Wall wall = Util.SelectSingleElementOfType(
            uidoc, typeof( Wall ), "a curtain wall", false )
            as Wall;

              if( null == wall )
              {
            message = "Please select a single "
              + "curtain wall element.";

            return Result.Failed;
              }
              else
              {
            LocationCurve locationcurve
              = wall.Location as LocationCurve;

            Curve curve = locationcurve.Curve;

            // move whole geometry over by length of wall:

            XYZ p = curve.GetEndPoint( 0 );
            XYZ q = curve.GetEndPoint( 1 );
            XYZ v = q - p;

            Transform tv = Transform.CreateTranslation( v );

            //curve = curve.get_Transformed( tv ); // 2013
            curve = curve.CreateTransformed( tv ); // 2014

            Creator creator = new Creator( doc );
            creator.CreateModelCurve( curve );

            Options opt = app.Create.NewGeometryOptions();
            opt.IncludeNonVisibleObjects = true;

            GeometryElement e = wall.get_Geometry( opt );

            foreach( GeometryObject obj in e )
            {
              curve = obj as Curve;

              if( null != curve )
              {
            //curve = curve.get_Transformed( tv ); // 2013
            curve = curve.CreateTransformed( tv ); // 2014
            creator.CreateModelCurve( curve );
              }
            }
            return Result.Succeeded;
              }
        }
Esempio n. 7
0
        public Result Execute(
            ExternalCommandData commandData,
            ref string message,
            ElementSet elements)
        {
            UIApplication app   = commandData.Application;
            UIDocument    uidoc = app.ActiveUIDocument;
            Document      doc   = uidoc.Document;

            Element e = Util.SelectSingleElement(
                uidoc, "an element");

            if (null == e)
            {
                message = "No element selected";
                return(Result.Failed);
            }

            // Trying to call this property returns the
            // compile time error: Property, indexer, or
            // event 'BoundingBox' is not supported by
            // the language; try directly calling
            // accessor method 'get_BoundingBox( View )'

            //BoundingBoxXYZ b = e.BoundingBox[null];

            View v = null;

            BoundingBoxXYZ b = e.get_BoundingBox(v);

            if (null == b)
            {
                v = commandData.View;
                b = e.get_BoundingBox(v);
            }

            if (null == b)
            {
                Util.InfoMsg(
                    Util.ElementDescription(e)
                    + " has no bounding box.");
            }
            else
            {
                using (Transaction tx = new Transaction(doc))
                {
                    tx.Start("Draw Model Line Bounding Box Outline");

                    Debug.Assert(b.Transform.IsIdentity,
                                 "expected identity bounding box transform");

                    string in_view = (null == v)
            ? "model space"
            : "view " + v.Name;

                    Util.InfoMsg(string.Format(
                                     "Element bounding box of {0} in "
                                     + "{1} extends from {2} to {3}.",
                                     Util.ElementDescription(e),
                                     in_view,
                                     Util.PointString(b.Min),
                                     Util.PointString(b.Max)));

                    Creator creator = new Creator(doc);

                    creator.DrawPolygon(new List <XYZ>(
                                            Util.GetBottomCorners(b)));

                    Transform rotation = Transform.CreateRotation(
                        XYZ.BasisZ, 60 * Math.PI / 180.0);

                    b = RotateBoundingBox(b, rotation);

                    Util.InfoMsg(string.Format(
                                     "Bounding box rotated by 60 degrees "
                                     + "extends from {0} to {1}.",
                                     Util.PointString(b.Min),
                                     Util.PointString(b.Max)));

                    creator.DrawPolygon(new List <XYZ>(
                                            Util.GetBottomCorners(b)));

                    tx.Commit();
                }
            }
            return(Result.Succeeded);
        }
        /// <summary>
        /// Improved implementation by Alexander Ignatovich
        /// supporting curved wall with curved window,
        /// second attempt, published April 10, 2015:
        /// </summary>
        public Result Execute3(
            ExternalCommandData commandData,
            ref string message,
            ElementSet elements)
        {
            UIApplication uiapp = commandData.Application;
            UIDocument    uidoc = uiapp.ActiveUIDocument;
            Application   app   = uiapp.Application;
            Document      doc   = uidoc.Document;
            View          view  = doc.ActiveView;

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

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

            Reference r = uidoc.Selection.PickObject(
                ObjectType.Element, "Select a wall");

            Element e = uidoc.Document.GetElement(r);

            Creator creator = new Creator(doc);

            Wall wall = e as Wall;

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

            using (Transaction tx = new Transaction(doc))
            {
                tx.Start("Wall Profile");

                // Get the external wall face for the profile
                // a little bit simpler than in the last realization

                Reference sideFaceReference
                    = HostObjectUtils.GetSideFaces(
                          wall, ShellLayerType.Exterior)
                      .First();

                Face face = wall.GetGeometryObjectFromReference(
                    sideFaceReference) as Face;

                // The normal of the wall external face.

                XYZ normal = wall.Orientation;

                // Offset curve copies for visibility.

                Transform offset = Transform.CreateTranslation(
                    5 * normal);

                // If the curve loop direction is counter-
                // clockwise, change its color to RED.

                Color colorRed = new Color(255, 0, 0);

                // Get edge loops as curve loops.

                IList <CurveLoop> curveLoops
                    = face.GetEdgesAsCurveLoops();

                foreach (var curveLoop in curveLoops)
                {
                    CurveArray curves = creapp.NewCurveArray();

                    foreach (Curve curve in curveLoop)
                    {
                        curves.Append(curve.CreateTransformed(
                                          offset));
                    }

                    var isCounterClockwize = curveLoop
                                             .IsCounterclockwise(normal);

                    // Create model lines for an curve loop if it is made

                    if (((LocationCurve)wall.Location).Curve
                        is Line)
                    {
                        Plane plane = creapp.NewPlane(curves);

                        SketchPlane sketchPlane
                            = SketchPlane.Create(doc, plane);

                        ModelCurveArray curveElements = credoc
                                                        .NewModelCurveArray(curves, sketchPlane);

                        if (isCounterClockwize)
                        {
                            SetModelCurvesColor(curveElements,
                                                view, colorRed);
                        }
                    }
                    else
                    {
                        foreach (var curve in curves.Cast <Curve>())
                        {
                            var curveElements = creator.CreateModelCurves(curve);
                            if (isCounterClockwize)
                            {
                                SetModelCurvesColor(curveElements, view, colorRed);
                            }
                        }
                    }
                }
                tx.Commit();
            }
            return(Result.Succeeded);
        }
        public Result Execute(
            ExternalCommandData commandData,
            ref string message,
            ElementSet elements)
        {
            UIApplication app = commandData.Application;
              UIDocument uidoc = app.ActiveUIDocument;
              Document doc = uidoc.Document;

              // retrieve selected floors, or all floors, if nothing is selected:

              List<Element> floors = new List<Element>();

              if( !Util.GetSelectedElementsOrAll(
            floors, uidoc, typeof( Floor ) ) )
              {
            Selection sel = uidoc.Selection;

            message = ( 0 < sel.Elements.Size )
              ? "Please select some floor elements."
              : "No floor elements found.";

            return Result.Failed;
              }

              Options opt = app.Application.Create.NewGeometryOptions();

              List<List<XYZ>> polygons
            = GetFloorBoundaryPolygons( floors, opt );

              int n = polygons.Count;

              Debug.Print(
            "{0} boundary loop{1} found.",
            n, Util.PluralSuffix( n ) );

              Creator creator = new Creator( doc );

              using( Transaction t = new Transaction( doc ) )
              {
            t.Start( "Draw Slab Boundaries" );

            creator.DrawPolygons( polygons );

            t.Commit();
              }

              return Result.Succeeded;
        }
        /// <summary>
        /// Improved implementation by Alexander Ignatovich
        /// supporting curved wall with curved window, 
        /// second attempt, published April 10, 2015:
        /// </summary>
        public Result Execute3(
            ExternalCommandData commandData,
            ref string message,
            ElementSet elements)
        {
            UIApplication uiapp = commandData.Application;
              UIDocument uidoc = uiapp.ActiveUIDocument;
              Application app = uiapp.Application;
              Document doc = uidoc.Document;
              View view = doc.ActiveView;

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

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

              Reference r = uidoc.Selection.PickObject(
            ObjectType.Element, "Select a wall" );

              Element e = uidoc.Document.GetElement( r );

              Creator creator = new Creator( doc );

              Wall wall = e as Wall;

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

              using( Transaction tx = new Transaction( doc ) )
              {
            tx.Start( "Wall Profile" );

            // Get the external wall face for the profile
            // a little bit simpler than in the last realization

            Reference sideFaceReference
              = HostObjectUtils.GetSideFaces(
            wall, ShellLayerType.Exterior )
              .First();

            Face face = wall.GetGeometryObjectFromReference(
              sideFaceReference ) as Face;

            // The normal of the wall external face.

            XYZ normal = wall.Orientation;

            // Offset curve copies for visibility.

            Transform offset = Transform.CreateTranslation(
              5 * normal );

            // If the curve loop direction is counter-
            // clockwise, change its color to RED.

            Color colorRed = new Color( 255, 0, 0 );

            // Get edge loops as curve loops.

            IList<CurveLoop> curveLoops
              = face.GetEdgesAsCurveLoops();

            foreach( var curveLoop in curveLoops )
            {
              CurveArray curves = creapp.NewCurveArray();

              foreach( Curve curve in curveLoop )
            curves.Append( curve.CreateTransformed(
              offset ) );

              var isCounterClockwize = curveLoop
            .IsCounterclockwise( normal );

              // Create model lines for an curve loop if it is made

              if( ( (LocationCurve) wall.Location ).Curve
            is Line )
              {
            Plane plane = creapp.NewPlane( curves );

            SketchPlane sketchPlane
              = SketchPlane.Create( doc, plane );

            ModelCurveArray curveElements = credoc
              .NewModelCurveArray( curves, sketchPlane );

            if( isCounterClockwize )
            {
              SetModelCurvesColor( curveElements,
                view, colorRed );
            }
              }
              else
              {
            foreach( var curve in curves.Cast<Curve>() )
            {
              var curveElements = creator.CreateModelCurves( curve );
              if( isCounterClockwize )
              {
                SetModelCurvesColor( curveElements, view, colorRed );
              }
            }
              }
            }
            tx.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;
        }
        public Result Execute(
            ExternalCommandData commandData,
            ref string message,
            ElementSet elements)
        {
            UIApplication app = commandData.Application;
              UIDocument uidoc = app.ActiveUIDocument;
              Document doc = uidoc.Document;

              List<Element> floors = new List<Element>();
              if( !Util.GetSelectedElementsOrAll(
            floors, uidoc, typeof( Floor ) ) )
              {
            Selection sel = uidoc.Selection;
            message = ( 0 < sel.Elements.Size )
              ? "Please select some floor elements."
              : "No floor elements found.";
            return Result.Failed;
              }

              Options opt = app.Application.Create.NewGeometryOptions();

              List<List<XYZ>> polygons
            = CmdSlabBoundary.GetFloorBoundaryPolygons(
              floors, opt );

              List<List<UV>> flat_polygons
            = Flatten( polygons );

              int i = 0, n = flat_polygons.Count;
              double[] areas = new double[n];
              double a, maxArea = 0.0;
              foreach( List<UV> polygon in flat_polygons )
              {
            a = GetSignedPolygonArea( polygon );
            if( Math.Abs( maxArea ) < Math.Abs( a ) )
            {
              maxArea = a;
            }
            areas[i++] = a;
              }

              Debug.Print(
            "{0} boundary loop{1} found.",
            n, Util.PluralSuffix( n ) );

              for( i = 0; i < n; ++i )
              {
            Debug.Print(
              "  Loop {0} area is {1} square feet{2}",
              i,
              Util.RealString( areas[i] ),
              ( areas[i].Equals( maxArea )
            ? ", outer loop of largest floor slab"
            : "" ) );
              }

              Creator creator = new Creator( doc );
              creator.DrawPolygons( polygons );

              return Result.Succeeded;
        }
Esempio n. 13
0
        static Transform _t = Transform.CreateTranslation(_offset); // 2014

        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;

            List <Element> walls = new List <Element>();

            //XYZ p;
            //List<XYZ> wall_start_points
            //  = walls.Select<Element, XYZ>( e => {
            //    Util.GetElementLocation( out p, e );
            //      return p; } )
            //        .ToList<XYZ>();

            if (!Util.GetSelectedElementsOrAll(
                    walls, uidoc, typeof(Wall)))
            {
                Selection sel = uidoc.Selection;
                //message = ( 0 < sel.Elements.Size ) // 2014
                message = (0 < sel.GetElementIds().Count) // 2015
          ? "Please select some wall elements."
          : "No wall elements found.";
                return(Result.Failed);
            }


            using (Transaction tx = new Transaction(doc))
            {
                tx.Start("Create model curve copies of analytical model curves");

                Creator creator = new Creator(doc);

                foreach (Wall wall in walls)
                {
                    AnalyticalModel am = wall.GetAnalyticalModel();

                    foreach (AnalyticalCurveType ct in _curveTypes)
                    {
                        IList <Curve> curves = am.GetCurves(ct);

                        int n = curves.Count;

                        Debug.Print("{0} {1} curve{2}.",
                                    n, ct, Util.PluralSuffix(n));

                        foreach (Curve curve in curves)
                        {
                            //creator.CreateModelCurve( curve.get_Transformed( _t ) ); // 2013

                            creator.CreateModelCurve(curve.CreateTransformed(_t)); // 2014
                        }
                    }
                }
                tx.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);
        }
        public Result Execute(
            ExternalCommandData commandData,
            ref string message,
            ElementSet elements)
        {
            UIApplication app   = commandData.Application;
            UIDocument    uidoc = app.ActiveUIDocument;
            Document      doc   = uidoc.Document;

            List <Element> floors = new List <Element>();

            if (!Util.GetSelectedElementsOrAll(
                    floors, uidoc, typeof(Floor)))
            {
                Selection sel = uidoc.Selection;
                message = (0 < sel.GetElementIds().Count)
          ? "Please select some floor elements."
          : "No floor elements found.";
                return(Result.Failed);
            }

            Options opt = app.Application.Create.NewGeometryOptions();

            List <List <XYZ> > polygons
                = CmdSlabBoundary.GetFloorBoundaryPolygons(
                      floors, opt);

            List <List <UV> > flat_polygons
                = Flatten(polygons);

            int i = 0, n = flat_polygons.Count;

            double[] areas = new double[n];
            double   a, maxArea = 0.0;

            foreach (List <UV> polygon in flat_polygons)
            {
                a = GetSignedPolygonArea(polygon);
                if (Math.Abs(maxArea) < Math.Abs(a))
                {
                    maxArea = a;
                }
                areas[i++] = a;
            }

            Debug.Print(
                "{0} boundary loop{1} found.",
                n, Util.PluralSuffix(n));

            for (i = 0; i < n; ++i)
            {
                Debug.Print(
                    "  Loop {0} area is {1} square feet{2}",
                    i,
                    Util.RealString(areas[i]),
                    (areas[i].Equals(maxArea)
            ? ", outer loop of largest floor slab"
            : ""));
            }

            Creator creator = new Creator(doc);

            creator.DrawPolygons(polygons);

            return(Result.Succeeded);
        }
Esempio n. 16
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;

            //// Select all pipes in the entire model.

            //List<Pipe> pipes = new List<Pipe>(
            //  new FilteredElementCollector( doc )
            //    .OfClass( typeof( Pipe ) )
            //    .ToElements()
            //    .Cast<Pipe>() );

            //int n = pipes.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.

            //  pipes.Clear();

            //  Selection sel = uidoc.Selection;

            //  //n = sel.Elements.Size; // 2014

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

            //  n = ids.Count; // 2015

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

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

            //  if( 1 < n )
            //  {
            //    //foreach( Element e in sel.Elements ) // 2014

            //    foreach( ElementId id in ids ) // 2015
            //    {
            //      Pipe c = doc.GetElement( id ) as Pipe;

            //      if( null != c )
            //      {
            //        pipes.Add( c );

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

            //          break;
            //        }
            //      }
            //    }
            //  }

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

            //  if( 2 != pipes.Count )
            //  {
            //    pipes.Clear();

            //    try
            //    {
            //      Reference r = sel.PickObject(
            //        ObjectType.Element,
            //        new PipeElementSelectionFilter(),
            //        "Please pick first pipe." );

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

            //    try
            //    {
            //      Reference r = sel.PickObject(
            //        ObjectType.Element,
            //        new PipeElementSelectionFilter(),
            //        "Please pick second pipe." );

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

            JtPairPicker <Pipe> picker
                = new JtPairPicker <Pipe>(uidoc);

            Result rc = picker.Pick();

            if (Result.Failed == rc)
            {
                message = _prompt;
            }

            if (Result.Succeeded != rc)
            {
                return(rc);
            }

            IList <Pipe> pipes = picker.Selected;

            // Check for same pipe system type.

            ElementId systemTypeId
                = pipes[0].MEPSystem.GetTypeId();

            Debug.Assert(pipes[1].MEPSystem.GetTypeId()
                         .IntegerValue.Equals(
                             systemTypeId.IntegerValue),
                         "expected two similar pipes");

            // Check for same pipe level.

            ElementId levelId = pipes[0].LevelId;

            Debug.Assert(
                pipes[1].LevelId.IntegerValue.Equals(
                    levelId.IntegerValue),
                "expected two pipes on same level");

            // Extract data from the two selected pipes.

            double wall_thickness = GetWallThickness(pipes[0]);

            Debug.Print("{0} has wall thickness {1}",
                        Util.ElementDescription(pipes[0]),
                        Util.RealString(wall_thickness));

            Curve c0 = pipes[0].GetCurve();
            Curve c1 = pipes[1].GetCurve();

            if (!(c0 is Line) || !(c1 is Line))
            {
                message = _prompt
                          + " Expected straight pipes.";

                return(Result.Failed);
            }

            XYZ p00 = c0.GetEndPoint(0);
            XYZ p01 = c0.GetEndPoint(1);

            XYZ p10 = c1.GetEndPoint(0);
            XYZ p11 = c1.GetEndPoint(1);

            XYZ v0 = p01 - p00;
            XYZ v1 = p11 - p10;

            if (!Util.IsParallel(v0, v1))
            {
                message = _prompt
                          + " Expected parallel pipes.";

                return(Result.Failed);
            }

            // Select the two pipe endpoints
            // that are farthest apart.

            XYZ p0 = p00.DistanceTo(p10) > p01.DistanceTo(p10)
        ? p00
        : p01;

            XYZ p1 = p10.DistanceTo(p0) > p11.DistanceTo(p0)
        ? p10
        : p11;

            XYZ pm = 0.5 * (p0 + p1);

            XYZ v = p1 - p0;

            if (Util.IsParallel(v, v0))
            {
                message = "The selected pipes are colinear.";
                return(Result.Failed);
            }

            // Normal vector of the plane defined by the
            // two parallel and offset pipes, which is
            // the plane hosting the rolling offset

            XYZ z = v.CrossProduct(v1);

            // Vector perpendicular to v0 and v0 and
            // z, i.e. vector pointing from the first pipe
            // to the second in the cross sectional view.

            XYZ w = z.CrossProduct(v1).Normalize();

            // Offset distance perpendicular to pipe direction

            double distanceAcross = Math.Abs(
                v.DotProduct(w));

            // Distance between endpoints parallel
            // to pipe direction

            double distanceAlong = Math.Abs(
                v.DotProduct(v1.Normalize()));

            Debug.Assert(Util.IsEqual(v.GetLength(),
                                      Math.Sqrt(distanceAcross * distanceAcross
                                                + distanceAlong * distanceAlong)),
                         "expected Pythagorean equality here");

            // The required offset pipe angle.

            double angle = 45 * Math.PI / 180.0;

            // The angle on the other side.

            double angle2 = 0.5 * Math.PI - angle;

            double length = distanceAcross * Math.Tan(angle2);

            double halfLength = 0.5 * length;

            // How long should the pipe stubs become?

            double remainingPipeLength
                = 0.5 * (distanceAlong - length);

            if (0 > v1.DotProduct(v))
            {
                v1.Negate();
            }

            v1 = v1.Normalize();

            XYZ q0 = p0 + remainingPipeLength * v1;

            XYZ q1 = p1 - remainingPipeLength * v1;

            using (Transaction tx = new Transaction(doc))
            {
                // Determine pipe diameter for creating
                // matching pipes and fittings

                Pipe pipe = pipes[0];

                double diameter = pipe
                                  .get_Parameter(bipDiameter) // "Diameter"
                                  .AsDouble();

                // Pipe type for calls to doc.Create.NewPipe

                PipeType pipe_type_standard
                    = new FilteredElementCollector(doc)
                      .OfClass(typeof(PipeType))
                      .Cast <PipeType>()
                      .Where <PipeType>(e
                                        => e.Name.Equals("Standard"))
                      .FirstOrDefault <PipeType>();

                Debug.Assert(
                    pipe_type_standard.Id.IntegerValue.Equals(
                        pipe.PipeType.Id.IntegerValue),
                    "expected all pipes in this simple "
                    + "model to use the same pipe type");

                tx.Start("Rolling Offset");

                if (_place_model_line)
                {
                    // Trim or extend existing pipes

                    (pipes[0].Location as LocationCurve).Curve
                        = Line.CreateBound(p0, q0);

                    (pipes[1].Location as LocationCurve).Curve
                        = Line.CreateBound(p1, q1);

                    // Add a model line for the rolling offset pipe

                    Creator creator = new Creator(doc);

                    Line line = Line.CreateBound(q0, q1);

                    creator.CreateModelCurve(line);

                    pipe = null;
                }
                else if (_place_fittings)
                {
                    // Set active work plane to the rolling
                    // offset plane... removed again, since
                    // this has no effect at all on the
                    // fitting placement or rotation.
                    //
                    //Plane plane = new Plane( z, q0 );
                    //
                    //SketchPlane sp = SketchPlane.Create(
                    //  doc, plane );
                    //
                    //uidoc.ActiveView.SketchPlane = sp;
                    //uidoc.ActiveView.ShowActiveWorkPlane();

                    FamilySymbol symbol
                        = new FilteredElementCollector(doc)
                          .OfClass(typeof(FamilySymbol))
                          .OfCategory(BuiltInCategory.OST_PipeFitting)
                          .Cast <FamilySymbol>()
                          .Where <FamilySymbol>(e
                                                => e.Family.Name.Contains("Elbow - Generic"))
                          .FirstOrDefault <FamilySymbol>();

                    // Set up first 45 degree elbow fitting

                    FamilyInstance fitting0 = doc.Create
                                              .NewFamilyInstance(q0, symbol,
                                                                 StructuralType.NonStructural);

                    fitting0.get_Parameter("Angle").Set(
                        45.0 * Math.PI / 180.0);

                    //fitting0.get_Parameter( bipDiameter ) // does not exist
                    //  .Set( diameter );

                    fitting0.get_Parameter("Nominal Radius")
                    .Set(0.5 * diameter);

                    Line axis = Line.CreateBound(p0, q0);
                    angle = z.AngleTo(XYZ.BasisZ);

                    ElementTransformUtils.RotateElement(
                        doc, fitting0.Id, axis, Math.PI - angle);

                    Connector con0 = Util.GetConnectorClosestTo(
                        fitting0, p0);

                    // Trim or extend existing pipe

                    (pipes[0].Location as LocationCurve).Curve
                        = Line.CreateBound(p0, con0.Origin);

                    // Connect pipe to fitting

                    Util.Connect(con0.Origin, pipe, fitting0);

                    // Set up second 45 degree elbow fitting

                    FamilyInstance fitting1 = doc.Create
                                              .NewFamilyInstance(q1, symbol,
                                                                 StructuralType.NonStructural);

                    fitting1.get_Parameter("Angle").Set(
                        45.0 * Math.PI / 180.0);

                    fitting1.get_Parameter("Nominal Radius")
                    .Set(0.5 * diameter);

                    axis = Line.CreateBound(
                        q1, q1 + XYZ.BasisZ);

                    ElementTransformUtils.RotateElement(
                        doc, fitting1.Id, axis, Math.PI);

                    axis = Line.CreateBound(q1, p1);

                    ElementTransformUtils.RotateElement(
                        doc, fitting1.Id, axis, Math.PI - angle);

                    Connector con1 = Util.GetConnectorClosestTo(
                        fitting1, p1);

                    (pipes[1].Location as LocationCurve).Curve
                        = Line.CreateBound(con1.Origin, p1);

                    Util.Connect(con1.Origin, fitting1, pipes[1]);

                    con0 = Util.GetConnectorClosestTo(
                        fitting0, pm);

                    con1 = Util.GetConnectorClosestTo(
                        fitting1, pm);

                    // Connecting one fitting to the other does
                    // not insert a pipe in between. If the
                    // system is edited later, however, the two
                    // fittings snap together.
                    //
                    //con0.ConnectTo( con1 );

                    // Create rolling offset pipe segment

                    //pipe = doc.Create.NewPipe( con0.Origin, // 2014
                    //  con1.Origin, pipe_type_standard );

                    pipe = Pipe.Create(doc,
                                       pipe_type_standard.Id, levelId, con0, con1); // 2015

                    pipe.get_Parameter(bipDiameter)
                    .Set(diameter);

                    // Connect rolling offset pipe segment
                    // with elbow fittings at each end

                    Util.Connect(con0.Origin, fitting0, pipe);
                    Util.Connect(con1.Origin, pipe, fitting1);
                }
                else
                {
                    if (_use_static_pipe_create)
                    {
                        // Element id arguments to Pipe.Create.

                        ElementId idSystem;
                        ElementId idType;
                        ElementId idLevel;

                        // All these values are invalid for idSystem:

                        ElementId idSystem1 = pipe.MEPSystem.Id;
                        ElementId idSystem2 = ElementId.InvalidElementId;
                        ElementId idSystem3 = PipingSystem.Create(
                            doc, pipe.MEPSystem.GetTypeId(), "Tbc")
                                              .Id;

                        // This throws an argument exception saying
                        // The systemTypeId is not valid piping system type.
                        // Parameter name: systemTypeId

                        //pipe = Pipe.Create( doc, idSystem,
                        //  idType, idLevel, q0, q1 );

                        // Retrieve pipe system type, e.g.
                        // hydronic supply.

                        PipingSystemType pipingSystemType
                            = new FilteredElementCollector(doc)
                              .OfClass(typeof(PipingSystemType))
                              .OfType <PipingSystemType>()
                              .FirstOrDefault(st
                                              => st.SystemClassification
                                              == MEPSystemClassification
                                              .SupplyHydronic);

                        if (null == pipingSystemType)
                        {
                            message = "Could not find hydronic supply piping system type";
                            return(Result.Failed);
                        }

                        idSystem = pipingSystemType.Id;

                        Debug.Assert(pipe.get_Parameter(
                                         BuiltInParameter.RBS_PIPING_SYSTEM_TYPE_PARAM)
                                     .AsElementId().IntegerValue.Equals(
                                         idSystem.IntegerValue),
                                     "expected same piping system element id");

                        // Retrieve the PipeType.

                        PipeType pipeType =
                            new FilteredElementCollector(doc)
                            .OfClass(typeof(PipeType))
                            .OfType <PipeType>()
                            .FirstOrDefault();

                        if (null == pipeType)
                        {
                            message = "Could not find pipe type";
                            return(Result.Failed);
                        }

                        idType = pipeType.Id;

                        Debug.Assert(pipe.get_Parameter(
                                         BuiltInParameter.ELEM_TYPE_PARAM)
                                     .AsElementId().IntegerValue.Equals(
                                         idType.IntegerValue),
                                     "expected same pipe type element id");

                        Debug.Assert(pipe.PipeType.Id.IntegerValue
                                     .Equals(idType.IntegerValue),
                                     "expected same pipe type element id");

                        // Retrieve the reference level.
                        // pipe.LevelId is not the correct source!

                        idLevel = pipe.get_Parameter(
                            BuiltInParameter.RBS_START_LEVEL_PARAM)
                                  .AsElementId();

                        // Create the rolling offset pipe.

                        pipe = Pipe.Create(doc,
                                           idSystem, idType, idLevel, q0, q1);
                    }
                    else
                    {
                        pipe = doc.Create.NewPipe(q0, q1,
                                                  pipe_type_standard);
                    }

                    pipe.get_Parameter(bipDiameter)
                    .Set(diameter);

                    // Connect rolling offset pipe segment
                    // directly with the neighbouring original
                    // pipes
                    //
                    //Util.Connect( q0, pipes[0], pipe );
                    //Util.Connect( q1, pipe, pipes[1] );

                    // NewElbowFitting performs the following:
                    // - select appropriate fitting family and type
                    // - place and orient a family instance
                    // - set its parameters appropriately
                    // - connect it with its neighbours

                    Connector con0 = Util.GetConnectorClosestTo(
                        pipes[0], q0);

                    Connector con = Util.GetConnectorClosestTo(
                        pipe, q0);

                    doc.Create.NewElbowFitting(con0, con);

                    Connector con1 = Util.GetConnectorClosestTo(
                        pipes[1], q1);

                    con = Util.GetConnectorClosestTo(
                        pipe, q1);

                    doc.Create.NewElbowFitting(con, con1);
                }

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

              List<Element> walls = new List<Element>();
              if( !Util.GetSelectedElementsOrAll(
            walls, uidoc, typeof( Wall ) ) )
              {
            Selection sel = uidoc.Selection;
            message = ( 0 < sel.Elements.Size )
              ? "Please select some wall elements."
              : "No wall elements found.";
            return Result.Failed;
              }

              Options opt = app.Application.Create.NewGeometryOptions();

              List<List<XYZ>> polygons
            = CmdWallProfile.GetWallProfilePolygons(
              walls, opt );

              int i = 0, n = polygons.Count;
              double[] areas = new double[n];
              double d, a, maxArea = 0.0;
              XYZ normal;
              foreach( List<XYZ> polygon in polygons )
              {
            GetPolygonPlane( polygon,
              out normal, out d, out a );
            if( Math.Abs( maxArea ) < Math.Abs( a ) )
            {
              maxArea = a;
            }
            areas[i++] = a;

            #if DEBUG

              // transform the 3D polygon into a horizontal plane
              // so we can use the 2D GetSignedPolygonArea() and
              // compare its results with the 3D calculation.

              // todo: compare the relative speed of
              // transforming 3d to 2d and using 2d area
              // calculation versus direct 3d area calculation.

              Transform t = GetTransformToZ( normal );

              List<XYZ> polygonHorizontal
            = ApplyTransform( polygon, t );

              List<UV> polygon2d
            = CmdSlabBoundaryArea.Flatten(
              polygonHorizontal );

              double a2
            = CmdSlabBoundaryArea.GetSignedPolygonArea(
              polygon2d );

              Debug.Assert( Util.IsEqual( a, a2 ),
            "expected same area from 2D and 3D calculations" );
            #endif

              }

              Debug.Print(
            "{0} boundary loop{1} found.",
            n, Util.PluralSuffix( n ) );

              for( i = 0; i < n; ++i )
              {
            Debug.Print(
              "  Loop {0} area is {1} square feet{2}",
              i,
              Util.RealString( areas[i] ),
              ( areas[i].Equals( maxArea )
            ? ", outer loop of largest wall"
            : "" ) );
              }

              Creator creator = new Creator( doc );
              creator.DrawPolygons( polygons );

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

              List<Element> walls = new List<Element>();
              if( !Util.GetSelectedElementsOrAll(
            walls, uidoc, typeof( Wall ) ) )
              {
            Selection sel = uidoc.Selection;
            message = ( 0 < sel.Elements.Size )
              ? "Please select some wall elements."
              : "No wall elements found.";
            return Result.Failed;
              }

              Options opt = app.Application.Create.NewGeometryOptions();

              List<List<XYZ>> polygons
            = GetWallProfilePolygons( walls, opt );

              int n = polygons.Count;

              Debug.Print(
            "{0} boundary loop{1} found.",
            n, Util.PluralSuffix( n ) );

              Creator creator = new Creator( doc );
              creator.DrawPolygons( polygons );

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

            // Retrieve selected walls, or all walls,
            // if nothing is selected:

            List <Element> walls = new List <Element>();

            if (!Util.GetSelectedElementsOrAll(
                    walls, uidoc, typeof(Wall)))
            {
                Selection sel = uidoc.Selection;
                message = (0 < sel.GetElementIds().Count)
          ? "Please select some wall elements."
          : "No wall elements found.";
                return(Result.Failed);
            }

            //int i; // 2011
            int    n;
            double halfThickness, layerOffset;
            //Creator creator = new Creator( doc );
            XYZ lcstart, lcend, v, w, p, q;

            using (Transaction tx = new Transaction(doc))
            {
                tx.Start("Draw wall layer sepearation lines");

                foreach (Wall wall in walls)
                {
                    string desc = Util.ElementDescription(wall);

                    LocationCurve curve
                        = wall.Location as LocationCurve;

                    if (null == curve)
                    {
                        message = desc + ": No wall curve found.";
                        return(Result.Failed);
                    }

                    // Wall centre line and thickness:

                    lcstart       = curve.Curve.GetEndPoint(0);
                    lcend         = curve.Curve.GetEndPoint(1);
                    halfThickness = 0.5 * wall.WallType.Width;
                    v             = lcend - lcstart;
                    v             = v.Normalize(); // one foot long
                    w             = XYZ.BasisZ.CrossProduct(v).Normalize();
                    if (wall.Flipped)
                    {
                        w = -w;
                    }

                    p = lcstart - 2 * v;
                    q = lcend + 2 * v;
                    Creator.CreateModelLine(doc, p, q);

                    q = p + halfThickness * w;
                    Creator.CreateModelLine(doc, p, q);

                    // Exterior edge

                    p = lcstart - v + halfThickness * w;
                    q = lcend + v + halfThickness * w;
                    Creator.CreateModelLine(doc, p, q);

                    //CompoundStructure structure = wall.WallType.CompoundStructure; // 2011
                    CompoundStructure structure = wall.WallType.GetCompoundStructure(); // 2012

                    if (null == structure)
                    {
                        message = desc + ": No compound structure "
                                  + "found. Is this a stacked wall?";

                        return(Result.Failed);
                    }

                    //CompoundStructureLayerArray layers = structure.Layers; // 2011
                    IList <CompoundStructureLayer> layers = structure.GetLayers(); // 2012

                    //i = 0; // 2011
                    //n = layers.Size; // 2011
                    n = layers.Count; // 2012

                    Debug.Print(
                        "{0} with thickness {1}"
                        + " has {2} layer{3}{4}",
                        desc,
                        Util.MmString(2 * halfThickness),
                        n, Util.PluralSuffix(n),
                        Util.DotOrColon(n));

                    if (0 == n)
                    {
                        // Interior edge

                        p = lcstart - v - halfThickness * w;
                        q = lcend + v - halfThickness * w;
                        Creator.CreateModelLine(doc, p, q);
                    }
                    else
                    {
                        layerOffset = halfThickness;
                        foreach (CompoundStructureLayer layer
                                 in layers)
                        {
                            Debug.Print(
                                "  Layer {0}: function {1}, "
                                + "thickness {2}",
                                //++i, // 2011
                                layers.IndexOf(layer), // 2012
                                layer.Function,
                                Util.MmString(layer.Width));

                            //layerOffset -= layer.Thickness; // 2011
                            layerOffset -= layer.Width; // 2012

                            p = lcstart - v + layerOffset * w;
                            q = lcend + v + layerOffset * w;
                            Creator.CreateModelLine(doc, p, q);
                        }
                    }
                    tx.Commit();
                }
            }
            return(Result.Succeeded);
        }
        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 pipes in the entire model.

              List<Pipe> pipes = new List<Pipe>(
            new FilteredElementCollector( doc )
              .OfClass( typeof( Pipe ) )
              .ToElements()
              .Cast<Pipe>() );

              int n = pipes.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.

            pipes.Clear();

            Selection sel = uidoc.Selection;

            n = sel.Elements.Size;

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

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

            if( 1 < n )
            {
              foreach( Element e in sel.Elements )
              {
            Pipe c = e as Pipe;

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

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

                break;
              }
            }
              }
            }

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

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

              try
              {
            Reference r = sel.PickObject(
              ObjectType.Element,
              new PipeElementSelectionFilter(),
              "Please pick first pipe." );

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

              try
              {
            Reference r = sel.PickObject(
              ObjectType.Element,
              new PipeElementSelectionFilter(),
              "Please pick second pipe." );

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

              // Extract data from the two selected pipes.

              Curve c0 = ( pipes[0].Location as LocationCurve ).Curve;
              Curve c1 = ( pipes[1].Location as LocationCurve ).Curve;

              if( !( c0 is Line ) || !( c1 is Line ) )
              {
            message = _prompt
              + " Expected straight pipes.";

            return Result.Failed;
              }

              XYZ p00 = c0.GetEndPoint( 0 );
              XYZ p01 = c0.GetEndPoint( 1 );

              XYZ p10 = c1.GetEndPoint( 0 );
              XYZ p11 = c1.GetEndPoint( 1 );

              XYZ v0 = p01 - p00;
              XYZ v1 = p11 - p10;

              if( !Util.IsParallel( v0, v1 ) )
              {
            message = _prompt
              + " Expected parallel pipes.";

            return Result.Failed;
              }

              // Select the two pipe endpoints
              // that are farthest apart.

              XYZ p0 = p00.DistanceTo( p10 ) > p01.DistanceTo( p10 )
            ? p00
            : p01;

              XYZ p1 = p10.DistanceTo( p0 ) > p11.DistanceTo( p0 )
            ? p10
            : p11;

              XYZ pm = 0.5 * ( p0 + p1 );

              XYZ v = p1 - p0;

              if( Util.IsParallel( v, v0 ) )
              {
            message = "The selected pipes are colinear.";
            return Result.Failed;
              }

              // Normal vector of the plane defined by the
              // two parallel and offset pipes, which is
              // the plane hosting the rolling offset

              XYZ z = v.CrossProduct( v1 );

              // Vector perpendicular to v0 and v0 and
              // z, i.e. vector pointing from the first pipe
              // to the second in the cross sectional view.

              XYZ w = z.CrossProduct( v1 ).Normalize();

              // Offset distance perpendicular to pipe direction

              double distanceAcross = Math.Abs(
            v.DotProduct( w ) );

              // Distance between endpoints parallel
              // to pipe direction

              double distanceAlong = Math.Abs(
            v.DotProduct( v1.Normalize() ) );

              Debug.Assert( Util.IsEqual( v.GetLength(),
            Math.Sqrt( distanceAcross * distanceAcross
              + distanceAlong * distanceAlong ) ),
            "expected Pythagorean equality here" );

              // The required offset pipe angle.

              double angle = 45 * Math.PI / 180.0;

              // The angle on the other side.

              double angle2 = 0.5 * Math.PI - angle;

              double length = distanceAcross * Math.Tan( angle2 );

              double halfLength = 0.5 * length;

              // How long should the pipe stubs become?

              double remainingPipeLength
            = 0.5 * ( distanceAlong - length );

              if( 0 > v1.DotProduct( v ) )
              {
            v1.Negate();
              }

              v1 = v1.Normalize();

              XYZ q0 = p0 + remainingPipeLength * v1;

              XYZ q1 = p1 - remainingPipeLength * v1;

              using( Transaction tx = new Transaction( doc ) )
              {
            // Determine pipe diameter for creating
            // matching pipes and fittings

            Pipe pipe = pipes[0];

            double diameter = pipe
              .get_Parameter( bipDiameter ) // "Diameter"
              .AsDouble();

            // Pipe type for calls to doc.Create.NewPipe

            PipeType pipe_type_standard
              = new FilteredElementCollector( doc )
            .OfClass( typeof( PipeType ) )
            .Cast<PipeType>()
            .Where<PipeType>( e
              => e.Name.Equals( "Standard" ) )
            .FirstOrDefault<PipeType>();

            Debug.Assert(
              pipe_type_standard.Id.IntegerValue.Equals(
            pipe.PipeType.Id.IntegerValue ),
              "expected all pipes in this simple "
              + "model to use the same pipe type" );

            tx.Start( "Rolling Offset" );

            if( _place_model_line )
            {
              // Trim or extend existing pipes

              ( pipes[0].Location as LocationCurve ).Curve
            = Line.CreateBound( p0, q0 );

              ( pipes[1].Location as LocationCurve ).Curve
            = Line.CreateBound( p1, q1 );

              // Add a model line for the rolling offset pipe

              Creator creator = new Creator( doc );

              Line line = Line.CreateBound( q0, q1 );

              creator.CreateModelCurve( line );

              pipe = null;
            }
            else if( _place_fittings )
            {
              // Set active work plane to the rolling
              // offset plane... removed again, since
              // this has no effect at all on the
              // fitting placement or rotation.
              //
              //Plane plane = new Plane( z, q0 );
              //
              //SketchPlane sp = SketchPlane.Create(
              //  doc, plane );
              //
              //uidoc.ActiveView.SketchPlane = sp;
              //uidoc.ActiveView.ShowActiveWorkPlane();

              FamilySymbol symbol
            = new FilteredElementCollector( doc )
              .OfClass( typeof( FamilySymbol ) )
              .OfCategory( BuiltInCategory.OST_PipeFitting )
              .Cast<FamilySymbol>()
              .Where<FamilySymbol>( e
                => e.Family.Name.Contains( "Elbow - Generic" ) )
              .FirstOrDefault<FamilySymbol>();

              // Set up first 45 degree elbow fitting

              FamilyInstance fitting0 = doc.Create
            .NewFamilyInstance( q0, symbol,
              StructuralType.NonStructural );

              fitting0.get_Parameter( "Angle" ).Set(
            45.0 * Math.PI / 180.0 );

              //fitting0.get_Parameter( bipDiameter ) // does not exist
              //  .Set( diameter );

              fitting0.get_Parameter( "Nominal Radius" )
            .Set( 0.5 * diameter );

              Line axis = Line.CreateBound( p0, q0 );
              angle = z.AngleTo( XYZ.BasisZ );

              ElementTransformUtils.RotateElement(
            doc, fitting0.Id, axis, Math.PI - angle );

              Connector con0 = Util.GetConnectorClosestTo(
            fitting0, p0 );

              // Trim or extend existing pipe

              ( pipes[0].Location as LocationCurve ).Curve
            = Line.CreateBound( p0, con0.Origin );

              // Connect pipe to fitting

              Util.Connect( con0.Origin, pipe, fitting0 );

              // Set up second 45 degree elbow fitting

              FamilyInstance fitting1 = doc.Create
            .NewFamilyInstance( q1, symbol,
              StructuralType.NonStructural );

              fitting1.get_Parameter( "Angle" ).Set(
            45.0 * Math.PI / 180.0 );

              fitting1.get_Parameter( "Nominal Radius" )
            .Set( 0.5 * diameter );

              axis = Line.CreateBound(
            q1, q1 + XYZ.BasisZ );

              ElementTransformUtils.RotateElement(
            doc, fitting1.Id, axis, Math.PI );

              axis = Line.CreateBound( q1, p1 );

              ElementTransformUtils.RotateElement(
            doc, fitting1.Id, axis, Math.PI - angle );

              Connector con1 = Util.GetConnectorClosestTo(
            fitting1, p1 );

              ( pipes[1].Location as LocationCurve ).Curve
            = Line.CreateBound( con1.Origin, p1 );

              Util.Connect( con1.Origin, fitting1, pipes[1] );

              con0 = Util.GetConnectorClosestTo(
            fitting0, pm );

              con1 = Util.GetConnectorClosestTo(
            fitting1, pm );

              // Connecting one fitting to the other does
              // not insert a pipe in between. If the
              // system is edited later, however, the two
              // fittings snap together.
              //
              //con0.ConnectTo( con1 );

              // Create rolling offset pipe segment

              pipe = doc.Create.NewPipe( con0.Origin,
            con1.Origin, pipe_type_standard );

              pipe.get_Parameter( bipDiameter )
            .Set( diameter );

              // Connect rolling offset pipe segment
              // with elbow fittings at each end

              Util.Connect( con0.Origin, fitting0, pipe );
              Util.Connect( con1.Origin, pipe, fitting1 );
            }
            else
            {
              if( _use_static_pipe_create )
              {
            // Element id arguments to Pipe.Create.

            ElementId idSystem;
            ElementId idType;
            ElementId idLevel;

            // All these values are invalid for idSystem:

            ElementId idSystem1 = pipe.MEPSystem.Id;
            ElementId idSystem2 = ElementId.InvalidElementId;
            ElementId idSystem3 = PipingSystem.Create(
              doc, pipe.MEPSystem.GetTypeId(), "Tbc" )
                .Id;

            // This throws an argument exception saying
            // The systemTypeId is not valid piping system type.
            // Parameter name: systemTypeId

            //pipe = Pipe.Create( doc, idSystem,
            //  idType, idLevel, q0, q1 );

            // Retrieve pipe system type, e.g.
            // hydronic supply.

            PipingSystemType pipingSystemType
              = new FilteredElementCollector( doc )
                .OfClass( typeof( PipingSystemType ) )
                .OfType<PipingSystemType>()
                .FirstOrDefault( st
                  => st.SystemClassification
                    == MEPSystemClassification
                      .SupplyHydronic );

            if( null == pipingSystemType )
            {
              message = "Could not find hydronic supply piping system type";
              return Result.Failed;
            }

            idSystem = pipingSystemType.Id;

            Debug.Assert( pipe.get_Parameter(
              BuiltInParameter.RBS_PIPING_SYSTEM_TYPE_PARAM )
                .AsElementId().IntegerValue.Equals(
                  idSystem.IntegerValue ),
                "expected same piping system element id" );

            // Retrieve the PipeType.

            PipeType pipeType =
              new FilteredElementCollector( doc )
                .OfClass( typeof( PipeType ) )
                .OfType<PipeType>()
                .FirstOrDefault();

            if( null == pipeType )
            {
              message = "Could not find pipe type";
              return Result.Failed;
            }

            idType = pipeType.Id;

            Debug.Assert( pipe.get_Parameter(
              BuiltInParameter.ELEM_TYPE_PARAM )
                .AsElementId().IntegerValue.Equals(
                  idType.IntegerValue ),
              "expected same pipe type element id" );

            Debug.Assert( pipe.PipeType.Id.IntegerValue
              .Equals( idType.IntegerValue ),
              "expected same pipe type element id" );

            // Retrieve the reference level.
            // pipe.LevelId is not the correct source!

            idLevel = pipe.get_Parameter(
              BuiltInParameter.RBS_START_LEVEL_PARAM )
                .AsElementId();

            // Create the rolling offset pipe.

            pipe = Pipe.Create( doc,
              idSystem, idType, idLevel, q0, q1 );
              }
              else
              {
            pipe = doc.Create.NewPipe( q0, q1,
              pipe_type_standard );
              }

              pipe.get_Parameter( bipDiameter )
            .Set( diameter );

              // Connect rolling offset pipe segment
              // directly with the neighbouring original
              // pipes
              //
              //Util.Connect( q0, pipes[0], pipe );
              //Util.Connect( q1, pipe, pipes[1] );

              // NewElbowFitting performs the following:
              // - select appropriate fitting family and type
              // - place and orient a family instance
              // - set its parameters appropriately
              // - connect it with its neighbours

              Connector con0 = Util.GetConnectorClosestTo(
            pipes[0], q0 );

              Connector con = Util.GetConnectorClosestTo(
            pipe, q0 );

              doc.Create.NewElbowFitting( con0, con );

              Connector con1 = Util.GetConnectorClosestTo(
            pipes[1], q1 );

              con = Util.GetConnectorClosestTo(
            pipe, q1 );

              doc.Create.NewElbowFitting( con, con1 );
            }

            tx.Commit();
              }
              return Result.Succeeded;
        }
Esempio n. 21
0
        public Result Execute(
            ExternalCommandData commandData,
            ref string message,
            ElementSet elements)
        {
            UIApplication app   = commandData.Application;
            UIDocument    uidoc = app.ActiveUIDocument;
            Document      doc   = uidoc.Document;

            List <Element> walls = new List <Element>();

            if (!Util.GetSelectedElementsOrAll(
                    walls, uidoc, typeof(Wall)))
            {
                Selection sel = uidoc.Selection;
                message = (0 < sel.GetElementIds().Count)
          ? "Please select some wall elements."
          : "No wall elements found.";
                return(Result.Failed);
            }

            Options opt = app.Application.Create.NewGeometryOptions();

            List <List <XYZ> > polygons
                = CmdWallProfile.GetWallProfilePolygons(
                      walls, opt);

            int i = 0, n = polygons.Count;

            double[] areas = new double[n];
            double   d, a, maxArea = 0.0;
            XYZ      normal;

            foreach (List <XYZ> polygon in polygons)
            {
                GetPolygonPlane(polygon,
                                out normal, out d, out a);
                if (Math.Abs(maxArea) < Math.Abs(a))
                {
                    maxArea = a;
                }
                areas[i++] = a;

#if DEBUG
                // transform the 3D polygon into a horizontal plane
                // so we can use the 2D GetSignedPolygonArea() and
                // compare its results with the 3D calculation.

                // todo: compare the relative speed of
                // transforming 3d to 2d and using 2d area
                // calculation versus direct 3d area calculation.


                Transform t = GetTransformToZ(normal);

                List <XYZ> polygonHorizontal
                    = ApplyTransform(polygon, t);

                List <UV> polygon2d
                    = CmdSlabBoundaryArea.Flatten(
                          polygonHorizontal);

                double a2
                    = CmdSlabBoundaryArea.GetSignedPolygonArea(
                          polygon2d);

                Debug.Assert(Util.IsEqual(a, a2),
                             "expected same area from 2D and 3D calculations");
#endif
            }

            Debug.Print(
                "{0} boundary loop{1} found.",
                n, Util.PluralSuffix(n));

            for (i = 0; i < n; ++i)
            {
                Debug.Print(
                    "  Loop {0} area is {1} square feet{2}",
                    i,
                    Util.RealString(areas[i]),
                    (areas[i].Equals(maxArea)
            ? ", outer loop of largest wall"
            : ""));
            }

            Creator creator = new Creator(doc);

            using (Transaction tx = new Transaction(doc))
            {
                tx.Start("Draw wall profile loops");
                creator.DrawPolygons(polygons);
                tx.Commit();
            }
            return(Result.Succeeded);
        }
        public Result Execute(
            ExternalCommandData commandData,
            ref string message,
            ElementSet elements)
        {
            UIApplication app = commandData.Application;
              UIDocument uidoc = app.ActiveUIDocument;
              Document doc = app.ActiveUIDocument.Document;

              // retrieve selected walls, or all walls,
              // if nothing is selected:

              List<Element> walls = new List<Element>();
              if( !Util.GetSelectedElementsOrAll(
            walls, uidoc, typeof( Wall ) ) )
              {
            Selection sel = uidoc.Selection;
            message = ( 0 < sel.Elements.Size )
              ? "Please select some wall elements."
              : "No wall elements found.";
            return Result.Failed;
              }

              //int i; // 2011
              int n;
              double halfThickness, layerOffset;
              Creator creator = new Creator( doc );
              XYZ lcstart, lcend, v, w, p, q;

              foreach( Wall wall in walls )
              {
            string desc = Util.ElementDescription( wall );

            LocationCurve curve
              = wall.Location as LocationCurve;

            if( null == curve )
            {
              message = desc + ": No wall curve found.";
              return Result.Failed;
            }

            // wall centre line and thickness:

            lcstart = curve.Curve.GetEndPoint( 0 );
            lcend = curve.Curve.GetEndPoint( 1 );
            halfThickness = 0.5 * wall.WallType.Width;
            v = lcend - lcstart;
            v = v.Normalize(); // one foot long
            w = XYZ.BasisZ.CrossProduct( v ).Normalize();
            if( wall.Flipped ) { w = -w; }

            p = lcstart - 2 * v;
            q = lcend + 2 * v;
            creator.CreateModelLine( p, q );

            q = p + halfThickness * w;
            creator.CreateModelLine( p, q );

            // exterior edge

            p = lcstart - v + halfThickness * w;
            q = lcend + v + halfThickness * w;
            creator.CreateModelLine( p, q );

            //CompoundStructure structure = wall.WallType.CompoundStructure; // 2011
            CompoundStructure structure = wall.WallType.GetCompoundStructure(); // 2012

            //CompoundStructureLayerArray layers = structure.Layers; // 2011
            IList<CompoundStructureLayer> layers = structure.GetLayers(); // 2012

            //i = 0; // 2011
            //n = layers.Size; // 2011
            n = layers.Count; // 2012

            Debug.Print(
              "{0} with thickness {1}"
              + " has {2} layer{3}{4}",
              desc,
              Util.MmString( 2 * halfThickness ),
              n, Util.PluralSuffix( n ),
              Util.DotOrColon( n ) );

            if( 0 == n )
            {
              // interior edge
              p = lcstart - v - halfThickness * w;
              q = lcend + v - halfThickness * w;
              creator.CreateModelLine( p, q );
            }
            else
            {
              layerOffset = halfThickness;
              foreach( CompoundStructureLayer layer
            in layers )
              {
            Debug.Print(
              "  Layer {0}: function {1}, "
              + "thickness {2}",
              //++i, // 2011
              layers.IndexOf( layer ), // 2012
              layer.Function,
              Util.MmString( layer.Width ) );

            //layerOffset -= layer.Thickness; // 2011
            layerOffset -= layer.Width; // 2012

            p = lcstart - v + layerOffset * w;
            q = lcend + v + layerOffset * w;
            creator.CreateModelLine( p, q );
              }
            }
              }
              return Result.Succeeded;
        }
Esempio n. 23
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;

            Wall wall = Util.SelectSingleElementOfType(
                uidoc, typeof(Wall), "a curtain wall", false)
                        as Wall;

            if (null == wall)
            {
                message = "Please select a single "
                          + "curtain wall element.";

                return(Result.Failed);
            }
            else
            {
                LocationCurve locationcurve
                    = wall.Location as LocationCurve;

                Curve curve = locationcurve.Curve;

                // move whole geometry over by length of wall:

                XYZ p = curve.GetEndPoint(0);
                XYZ q = curve.GetEndPoint(1);
                XYZ v = q - p;

                Transform tv = Transform.CreateTranslation(v);

                //curve = curve.get_Transformed( tv ); // 2013
                curve = curve.CreateTransformed(tv); // 2014

                Creator creator = new Creator(doc);
                creator.CreateModelCurve(curve);

                Options opt = app.Create.NewGeometryOptions();
                opt.IncludeNonVisibleObjects = true;

                GeometryElement e = wall.get_Geometry(opt);

                using (Transaction t = new Transaction(doc))
                {
                    t.Start("Create Model Curves");

                    foreach (GeometryObject obj in e)
                    {
                        curve = obj as Curve;

                        if (null != curve)
                        {
                            //curve = curve.get_Transformed( tv ); // 2013
                            curve = curve.CreateTransformed(tv); // 2014
                            creator.CreateModelCurve(curve);
                        }
                    }
                    t.Commit();
                }
                return(Result.Succeeded);
            }
        }