예제 #1
0
        public static Elements.WallByProfile[] WallsFromRevitWall(ADSK.Wall wall, Document doc)
        {
            var side_faces = HostObjectUtils.GetSideFaces(wall, ShellLayerType.Exterior);

            if (side_faces.Count != 1)
            {
                throw new InvalidOperationException($"This wall has ${(side_faces.Count < 1 ? "not enough" : "too many")} interior faces");
            }

            var wallFace = doc.GetElement(side_faces[0]).GetGeometryObjectFromReference(side_faces[0]);

            if (!(wallFace is PlanarFace))
            {
                throw new InvalidCastException("This wall does not have planar faces");
            }

            var wallPlane = wallFace as PlanarFace;
            var profiles  = wallPlane.GetProfiles();

            var centerline = (wall.Location as LocationCurve).Curve;

            var line = new ElemGeom.Line(centerline.GetEndPoint(0).ToVector3(true), centerline.GetEndPoint(1).ToVector3(true));

            var walls = profiles.Select(p => new WallByProfile(p.Reverse(),
                                                               Elements.Units.FeetToMeters(wall.Width),
                                                               line));

            return(walls.ToArray());
        }
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            var uiapp = commandData.Application;
            var uidoc = uiapp.ActiveUIDocument;
            var doc   = uidoc.Document;
            var sel   = uidoc.Selection;

            var wall = sel.PickObject(ObjectType.Element, doc.GetSelectionFilter(m => m is Wall)).GetElement(doc) as Wall;

            var facesoutRef = HostObjectUtils.GetSideFaces(wall, ShellLayerType.Exterior);

            var facesinRef = HostObjectUtils.GetSideFaces(wall, ShellLayerType.Interior);

            var faceout = wall.GetGeometryObjectFromReference(facesoutRef.First()) as Face;
            var facein  = wall.GetGeometryObjectFromReference(facesinRef.First()) as Face;

            var area = default(double);

            area += faceout.Area;
            area += facein.Area;
            area  = UnitUtils.ConvertFromInternalUnits(area, DisplayUnitType.DUT_SQUARE_METERS);

            area = Math.Round(area, 3);

            MessageBox.Show(area.ToString() + "m^2");

            return(Result.Succeeded);
        }
예제 #3
0
        private WallCollection GetWallInformation(UIDocument uidoc, Document revitDoc, Application app, Wall wall, WallType WallType)
        {
            Autodesk.Revit.Creation.Document    credoc = revitDoc.Create;
            Autodesk.Revit.Creation.Application creapp = app.Create;
            View view = revitDoc.ActiveView;

            ElementType type  = WallType as ElementType;
            Parameter   b     = type.get_Parameter((BuiltInParameter.WALL_ATTR_WIDTH_PARAM));
            double      width = b.AsDouble() / 2;

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

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

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

            // The normal of the wall external face.
            XYZ normal = face.ComputeNormal(new UV(0, 0));

            // Offset curve copies for visibility.
            Transform offset = Transform.CreateTranslation(width * normal);

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


            // Get edge loops as curve loops.
            IList <CurveLoop> curveLoops = face.GetEdgesAsCurveLoops();

            // ExporterIFCUtils class can also be used for
            // non-IFC purposes. The SortCurveLoops method
            // sorts curve loops (edge loops) so that the
            // outer loops come first.
            IList <IList <CurveLoop> > curveLoopLoop = ExporterIFCUtils.SortCurveLoops(curveLoops);
            List <List <Curve> >       Walls         = new List <List <Curve> >();
            WallCollection             WCCC          = new WallCollection();

            foreach (IList <CurveLoop> curveLoops2 in curveLoopLoop)
            {
                foreach (CurveLoop curveLoop2 in curveLoops2)
                {
                    // Check if curve loop is counter-clockwise.

                    CurveArray   curves = creapp.NewCurveArray();
                    List <Curve> CC     = new List <Curve>();
                    foreach (Curve curve in curveLoop2)
                    {
                        curves.Append(curve.CreateTransformed(offset));
                        CC.Add(curve.CreateTransformed(offset));
                    }
                    // Create model lines for an curve loop.
                    Walls.Add(CC);
                    WCCC.AddWall(CC);
                }
            }

            return(WCCC);
        }
예제 #4
0
        private void SetWindowData(WindowData windowData)
        {
            // Collect existing windows
            List <FamilyInstance> windowElements = _doc.CollectElements <FamilyInstance>(BuiltInCategory.OST_Windows);

            List <FamilyInstance> newTrims = new List <FamilyInstance>();

            _tt.Start();

            // Get existing window sizes
            foreach (FamilyInstance window in windowElements)
            {
                // Get the type of window to retrieve it's data
                Element    wnTp        = _doc.GetElement(window.GetTypeId());
                double     winHt       = wnTp.get_Parameter(BuiltInParameter.WINDOW_HEIGHT).AsDouble();
                double     winWd       = wnTp.get_Parameter(BuiltInParameter.WINDOW_WIDTH).AsDouble();
                HostObject winHost     = window.Host as HostObject;
                Level      winLevel    = (Level)_doc.GetElement(window.LevelId);
                XYZ        winLocation = ((LocationPoint)window.Location).Point;

                string newTypeName = $"{windowData.StyleCategory}-{Math.Round((double)((int)winWd * 12))}-{Math.Round((double)((int)winHt * 12))}";

                window.Symbol = windowData.Types.FirstOrDefault(type => type.Name == newTypeName)
                                ?? CreateWindowType(windowData.Types[0], windowData.StyleCategory, winWd, winHt);

                // Create new window trim at window locations on the exterior face of the host wall if on a window of specific size ranges
                if (windowData.Trim?.Type != null && (winWd > 1.9 && winWd < 5.9) && (winHt > 1.9 && winHt < 5.9))
                {
                    IList <Reference> sideFaces = HostObjectUtils.GetSideFaces(winHost, ShellLayerType.Exterior);
                    Face           face         = _doc.GetElement(sideFaces[0]).GetGeometryObjectFromReference(sideFaces[0]) as Face;
                    UV             uvLoc        = face.Project(winLocation).UVPoint;
                    XYZ            normal       = face.ComputeNormal(uvLoc);
                    XYZ            refDir       = normal.CrossProduct(XYZ.BasisZ);
                    FamilyInstance winTrim      = _doc.Create.NewFamilyInstance(winLocation, (FamilySymbol)windowData.Trim.Type, winHost, StructuralType.NonStructural);

                    newTrims.Add(winTrim);

                    // Change the width and height of the newly created trims
                    winTrim.SetParameter("Opening Height", winHt);
                    winTrim.SetParameter("Opening Width", winWd);
                }
            }

            // Setting the parameters for the newly placed window trim
            if (newTrims.Count > 0)
            {
                foreach (FamilyInstance trim in newTrims)
                {
                    trim.SetParameter("Top Profile", windowData.Trim.TopCategory);
                    trim.SetParameter("Bottom Profile", windowData.Trim.BottomCategory);
                    trim.SetParameter("Side Profile", windowData.Trim.SideCategory);
                    trim.SetParameter("Shutter", windowData.ShutterCategory);
                    trim.SetParameter("Top Key", windowData.KeyCategory);
                }
            }

            _tt.Commit();
        }
예제 #5
0
        /// <summary>
        /// This node will return the interior face or faces for the input host object. This particular method works for walls.
        /// </summary>
        /// <param name="hostObject">The host object to retrieve interior faces for.</param>
        /// <returns></returns>
        public static IEnumerable <List <Surface> > InteriorSurface(global::Revit.Elements.Element hostObject)
        {
            Autodesk.Revit.DB.HostObject internalHost = hostObject.InternalElement as Autodesk.Revit.DB.HostObject;

            IList <Reference> sideRefs = HostObjectUtils.GetSideFaces(internalHost, ShellLayerType.Interior);

            List <Autodesk.Revit.DB.Face> exteriorGeometryObjects = new List <Autodesk.Revit.DB.Face>(sideRefs.Select(r => internalHost.GetGeometryObjectFromReference(r)).Cast <Autodesk.Revit.DB.Face>());

            return(exteriorGeometryObjects.Select(g => g.ToProtoType(true).ToList()));
        }
 /// <summary>
 /// Return a `StableRepresentation` for a linked wall's exterior face.
 /// </summary>
 public string GetFaceRefRepresentation( 
   Wall wall, 
   Document doc, 
   RevitLinkInstance instance )
 {
   Reference faceRef = HostObjectUtils.GetSideFaces( 
     wall, ShellLayerType.Exterior ).FirstOrDefault();
   Reference stRef = faceRef.CreateLinkReference( instance );
   string stable = stRef.ConvertToStableRepresentation( doc );
   return stable;
 }
예제 #7
0
        public static Transform getLocalCoordinates(Element element, Boolean isStruct, UIDocument uidoc)
        {
            Transform transform = null;

            int isstruct = 1;


            if (isStruct == true)
            {
                isstruct = -1;
            }

            if (element is Wall)
            {
                Wall wall = element as Wall;

                LocationCurve lc   = wall.Location as LocationCurve;
                Line          line = lc.Curve as Line;

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

                Face face = uidoc.Document.GetElement(sideFaces[0]).GetGeometryObjectFromReference(sideFaces[0]) as Face;

                Reference reference = face.Reference;

                UV uv = new UV(0, 0);

                XYZ wallfacedir = face.ComputeNormal(uv) as XYZ;

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

                BoundingBoxXYZ bb   = wall.get_BoundingBox(null);
                double         minZ = bb.Min.Z;
                double         maxZ = bb.Max.Z;

                double w = v.GetLength();
                double h = maxZ - minZ;

                XYZ midpoint = p + 0.5 * v;

                XYZ up = XYZ.BasisZ;

                XYZ walldir = wallfacedir.CrossProduct(up);

                transform        = Transform.Identity;
                transform.Origin = new XYZ(midpoint.X, midpoint.Y, 0);
                transform.BasisX = walldir.Normalize() * isstruct * -1;
                transform.BasisY = up;
                transform.BasisZ = wallfacedir * isstruct;
            }
            return(transform);
        }
예제 #8
0
        public void AddFaceBasedFamilyToLinks(Document doc)
        {
            ElementId alignedLinkId = new ElementId(125929);

            // Get symbol

            ElementId symbolId = new ElementId(126580);

            FamilySymbol fs = doc.GetElement(symbolId)
                              as FamilySymbol;

            // Aligned

            RevitLinkInstance linkInstance = doc.GetElement(
                alignedLinkId) as RevitLinkInstance;

            Document linkDocument = linkInstance
                                    .GetLinkDocument();

            FilteredElementCollector wallCollector
                = new FilteredElementCollector(linkDocument);

            wallCollector.OfClass(typeof(Wall));

            Wall targetWall = wallCollector.FirstElement()
                              as Wall;

            Reference exteriorFaceRef
                = HostObjectUtils.GetSideFaces(
                      targetWall, ShellLayerType.Exterior)
                  .First <Reference>();

            Reference linkToExteriorFaceRef
                = exteriorFaceRef.CreateLinkReference(
                      linkInstance);

            Line wallLine = (targetWall.Location
                             as LocationCurve).Curve as Line;

            XYZ wallVector = (wallLine.GetEndPoint(1)
                              - wallLine.GetEndPoint(0)).Normalize();

            using (Transaction t = new Transaction(doc))
            {
                t.Start("Add to face");

                doc.Create.NewFamilyInstance(
                    linkToExteriorFaceRef, XYZ.Zero,
                    wallVector, fs);

                t.Commit();
            }
        }
예제 #9
0
        public Face getWallExterior(Wall pickedWall)
        {
            // Get the side faces
            IList <Reference> sideFaces =
                HostObjectUtils.GetSideFaces(pickedWall,
                                             ShellLayerType.Exterior);
            // access the side face
            Face face =
                doc.GetElement(sideFaces[0])
                .GetGeometryObjectFromReference(sideFaces[0]) as Face;

            return(face);
        }
예제 #10
0
        // Get Profile--------------------------------------------------------------------
        public static List <XYZ> Get_Profile(Document doc, Element element)
        {
            List <XYZ> list_Profile_point = new List <XYZ>();

            try
            {
                IList <Reference> sideFaces = null;
                if (element.Category.Name == "Walls")
                {
                    sideFaces = HostObjectUtils.GetSideFaces(element as Wall, ShellLayerType.Exterior);
                }
                else
                {
                    sideFaces = HostObjectUtils.GetTopFaces(element as Floor);
                }

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

                // The normal of the wall external face.
                XYZ normal = face.ComputeNormal(new UV(0, 0));

                // Get edge loops as curve loops.
                IList <CurveLoop> curveLoops = face.GetEdgesAsCurveLoops();

                // ExporterIFCUtils class can also be used for
                // non-IFC purposes. The SortCurveLoops method
                // sorts curve loops (edge loops) so that the
                // outer loops come first.
                IList <IList <CurveLoop> > curveLoopLoop = ExporterIFCUtils.SortCurveLoops(curveLoops);
                foreach (IList <CurveLoop> curveLoops2 in curveLoopLoop)
                {
                    foreach (CurveLoop curveLoop2 in curveLoops2)
                    {
                        // Check if curve loop is counter-clockwise.
                        bool isCCW = curveLoop2.IsCounterclockwise(normal);
                        foreach (Curve curve in curveLoop2)
                        {
                            list_Profile_point.Add(curve.GetEndPoint(0));
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            return(list_Profile_point);
        }
예제 #11
0
        public void MirrorWall(Document doc, Wall wall)
        {
            Reference reference = HostObjectUtils.GetSideFaces(wall, ShellLayerType.Exterior).First();

            //get one of the wall's major side faces
            Face face = wall.GetGeometryObjectFromReference(reference) as Face;

            UV bboxMin = face.GetBoundingBox().Min;
            //create a plane based on the side face with an offset of 10 in the X & Y directions
            Plane plane =
                Plane.CreateByNormalAndOrigin(face.ComputeNormal(bboxMin),
                                              face.Evaluate(bboxMin).Add(new XYZ(10, 10, 0)));

            ElementTransformUtils.MirrorElement(doc, wall.Id, plane);
        }
        /// <summary>Получение наружного Face для стены</summary>
        /// <param name="wall">Стена</param>
        /// <param name="shellLayerType">Тип получаемого Face</param>
        /// <returns></returns>
        public static Face GetSideFaceFromWall(Wall wall, ShellLayerType shellLayerType)
        {
            Face face = null;
            IList <Reference> sideFaces = null;

            if (shellLayerType == ShellLayerType.Exterior)
            {
                sideFaces = HostObjectUtils.GetSideFaces(wall, ShellLayerType.Exterior);
            }
            if (shellLayerType == ShellLayerType.Interior)
            {
                sideFaces = HostObjectUtils.GetSideFaces(wall, ShellLayerType.Interior);
            }
            if (sideFaces != null)
            {
                face = wall.GetGeometryObjectFromReference(sideFaces[0]) as Face;
            }
            return(face);
        }
예제 #13
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            Autodesk.Revit.DB.HostObject host = null;
            if (!DA.GetData("Host", ref host) || host is null)
            {
                return;
            }

            var doc = Revit.ActiveDBDocument;

            try
            {
                var bottom = HostObjectUtils.GetBottomFaces(host).Select(reference => new Types.Face(reference, doc));
                DA.SetDataList("Bottom", bottom);
            }
            catch (Autodesk.Revit.Exceptions.ArgumentException) { }

            try
            {
                var top = HostObjectUtils.GetTopFaces(host).Select(reference => new Types.Face(reference, doc));
                DA.SetDataList("Top", top);
            }
            catch (Autodesk.Revit.Exceptions.ArgumentException) { }

            try
            {
                var interior = HostObjectUtils.GetSideFaces(host, ShellLayerType.Interior).Select(reference => new Types.Face(reference, doc));
                DA.SetDataList("Interior", interior);
            }
            catch (Autodesk.Revit.Exceptions.ArgumentException) { }

            try
            {
                var exterior = HostObjectUtils.GetSideFaces(host, ShellLayerType.Exterior).Select(reference => new Types.Face(reference, doc));
                DA.SetDataList("Exterior", exterior);
            }
            catch (Autodesk.Revit.Exceptions.ArgumentException) { }
        }
예제 #14
0
        /// <summary>
        /// Alternative implementation published January 23, 2015:
        /// http://thebuildingcoder.typepad.com/blog/2015/01/getting-the-wall-elevation-profile.html
        /// </summary>
        public Result Execute2(
            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);

            Wall wall = e as Wall;

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

                // Get the external wall face for the profile

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

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

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

                // The normal of the wall external face.

                XYZ normal = face.ComputeNormal(new UV(0, 0));

                // 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();

                // ExporterIFCUtils class can also be used for
                // non-IFC purposes. The SortCurveLoops method
                // sorts curve loops (edge loops) so that the
                // outer loops come first.

                IList <IList <CurveLoop> > curveLoopLoop
                    = ExporterIFCUtils.SortCurveLoops(
                          curveLoops);

                foreach (IList <CurveLoop> curveLoops2
                         in curveLoopLoop)
                {
                    foreach (CurveLoop curveLoop2 in curveLoops2)
                    {
                        // Check if curve loop is counter-clockwise.

                        bool isCCW = curveLoop2.IsCounterclockwise(
                            normal);

                        CurveArray curves = creapp.NewCurveArray();

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

                        // Create model lines for an curve loop.

                        //Plane plane = creapp.NewPlane( curves ); // 2016

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

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

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

                        if (isCCW)
                        {
                            foreach (ModelCurve mcurve in curveElements)
                            {
                                OverrideGraphicSettings overrides
                                    = view.GetElementOverrides(
                                          mcurve.Id);

                                overrides.SetProjectionLineColor(
                                    colorRed);

                                view.SetElementOverrides(
                                    mcurve.Id, overrides);
                            }
                        }
                    }
                }
                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
                // 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);
        }
예제 #16
0
        private static List <Polygon> GetProfile(this Autodesk.Revit.DB.Element element)
        {
            Document          doc             = element.Document;
            List <Polygon>    polygons        = new List <Polygon>();
            IList <Reference> firstSideFaces  = null;
            IList <Reference> secondSideFaces = null;

            switch (element)
            {
            case Wall revitWall:
                //use host object utils to get the outside face
                firstSideFaces  = HostObjectUtils.GetSideFaces(revitWall, ShellLayerType.Exterior);
                secondSideFaces = HostObjectUtils.GetSideFaces(revitWall, ShellLayerType.Interior);
                break;

            case Autodesk.Revit.DB.Floor revitFloor:
                firstSideFaces  = HostObjectUtils.GetTopFaces(revitFloor);
                secondSideFaces = HostObjectUtils.GetBottomFaces(revitFloor);
                break;
            }
            Element faceElement = doc.GetElement(firstSideFaces[0]);

            if (!(faceElement.GetGeometryObjectFromReference(firstSideFaces[0]) is Face exteriorFace) || !(faceElement.GetGeometryObjectFromReference(secondSideFaces[0]) is Face interiorFace))
            {
                return(null);
            }
            //this lets us pick the biggest face of the two sides. This is important because we want the shapes to close. 😁
            Face face = exteriorFace.Area > interiorFace.Area ? exteriorFace : interiorFace;
            // get the edges as curve loops and use the IFCUtils to sort them
            // credit: https://thebuildingcoder.typepad.com/blog/2015/01/getting-the-wall-elevation-profile.html
            IList <CurveLoop> curveLoops = face.GetEdgesAsCurveLoops();
            //this does the sorting so outside is the first item
            IList <CurveLoop> loops = ExporterIFCUtils.SortCurveLoops(curveLoops)[0];

            for (int i = 0; i < loops.Count; i++)
            {
                //here for outermost loop
                if (i == 0)
                {
                    var            outer    = loops[i];
                    List <Vector3> vertices = new List <Vector3>();
                    foreach (Autodesk.Revit.DB.Curve c in outer)
                    {
                        vertices.Add(c.GetEndPoint(0).ToVector3());
                    }
                    polygons.Add(new Polygon(vertices));
                }
                //here for the inner loops (voids)
                else
                {
                    var            inner    = loops[i];
                    List <Vector3> vertices = new List <Vector3>();
                    foreach (Autodesk.Revit.DB.Curve c in inner)
                    {
                        vertices.Add(c.GetEndPoint(0).ToVector3());
                    }
                    Polygon innerPolygon = new Polygon(vertices);
                    polygons.Add(innerPolygon);
                }
            }

            return(polygons);
        }
예제 #17
0
        public List <EdgeSegment> GetRawData(Room room,
                                             double DistanceToWall, double UnitWidth)
        {
            //Used to store the wall object.
            List <EdgeSegment> rSegments = new List <EdgeSegment>();

            #region The basics and datas
            const double er  = 0.0001;//used for error correction.
            Document     doc = room.Document;
            Autodesk.Revit.ApplicationServices.Application app = doc.Application;
            //get the level height of floor and ceiling
            //!!!!!current not consider different ceiling height or floor.Need improving.
            double levelC = room.ClosedShell.GetBoundingBox().Max.Z;
            double levelF = room.ClosedShell.GetBoundingBox().Min.Z;
            //Custom input data.
            double dist2W = DistanceToWall;
            double unitW  = UnitWidth;
            #endregion

            //get the boundary segments list
            IList <IList <BoundarySegment> > boundarys =
                room.GetBoundarySegments(new SpatialElementBoundaryOptions());

            //Loop through all the wall segment needed to oprate on
            //first layer is each boundary loop(in case a room has multiple boundaries)
            foreach (IList <BoundarySegment> groupSegments in boundarys)
            {
                //The stack is for the segments(one wall can be several segments)
                //The queue is for the wall after merging the segments.
                Stack <EdgeSegment> eSegments       = new Stack <EdgeSegment>();
                List <EdgeSegment>  eSegmentsMerged = new List <EdgeSegment>();

                //Second layer is the actual segment
                //in this loop process each segment opening info and log them
                foreach (BoundarySegment segment in groupSegments)
                {
                    #region Create the object,get the inner edge of a wall segment
                    EdgeSegment theSeg = new EdgeSegment();
                    Curve       segCrv = segment.GetCurve();
                    XYZ         start  = segCrv.GetEndPoint(0);
                    XYZ         end    = segCrv.GetEndPoint(1);
                    XYZ         normal;
                    theSeg.levelC = levelC;
                    theSeg.levelF = levelF;
                    theSeg.start  = new XYZ(start.X, start.Y, levelF);
                    theSeg.end    = new XYZ(end.X, end.Y, levelF);
                    #endregion

                    //The boundary segment may not be a wall
                    Element wallOrNot = doc.GetElement(segment.ElementId);

                    #region Seperate different category(Wall,Column or others)
                    Categories docCat   = doc.Settings.Categories;
                    ElementId  idColumn = docCat.get_Item(BuiltInCategory.OST_Columns).Id;
                    ElementId  idWall   = docCat.get_Item(BuiltInCategory.OST_Walls).Id;
                    //Case 1-A column or the end of a single wall.
                    if ((wallOrNot == null) || (wallOrNot.Category.Id.Equals(idColumn)))
                    {
                        //The room segments always search counterclockwise
                        //Thus compute the normal as follow
                        //Other data is not needed.Treat it as a full wall.
                        XYZ line = end - start;
                        normal        = new XYZ(-line.Y, line.X, 0);
                        theSeg.normal = normal / normal.GetLength();
                        eSegments.Push(theSeg);
                        continue;
                    }
                    //Case 2-Not column or wall.(Most likely curtain)Mark as noPanel.
                    if (!(wallOrNot.Category.Id.Equals(idWall)))
                    {
                        theSeg.NoPanel = true;
                        eSegments.Push(theSeg);
                        continue;
                    }
                    //Case 3-Walls
                    Wall theWall = wallOrNot as Wall;
                    #endregion

                    #region Get the sideface of a wall and get the profile curves
                    IList <Reference> sideFaces =
                        HostObjectUtils.GetSideFaces(theWall, ShellLayerType.Exterior);
                    //get the real face(why so long???)
                    Face face = doc.GetElement(sideFaces[0])
                                .GetGeometryObjectFromReference(sideFaces[0]) as Face;
                    //get edge loops as curveloops
                    IList <CurveLoop> openLoops = face.GetEdgesAsCurveLoops();
                    #endregion

                    //Some basic properties of the face.
                    normal = face.ComputeNormal(new UV(0, 0));
                    Plane plane = Plane.CreateByNormalAndOrigin(normal, start);

                    #region Check if curves are on the inner plane or not.
                    //(Might be on the other side of the wall)
                    //Log the correction vector in correction.
                    Curve checkCurve = openLoops[0].GetEnumerator().Current;
                    plane.Project(checkCurve.GetEndPoint(1), out UV uv, out double dist);
                    Transform correction = Transform.CreateTranslation(new XYZ(0, 0, 0));
                    if (dist > er) //Same wired reason.See "const double er" up front.
                    {
                        normal     = -normal;
                        correction = Transform.CreateTranslation(dist * normal);
                        plane      = Plane.CreateByNormalAndOrigin(normal, start);
                    }
                    #endregion

                    //Store all the endpoints and horizontal curves.
                    List <XYZ>   points = new List <XYZ>();
                    List <Curve> hoCrvs = new List <Curve>();
                    foreach (CurveLoop curveloop in openLoops)
                    {
                        foreach (Curve curve in curveloop)
                        {
                            points.Add(correction.OfPoint(curve.GetEndPoint(0)));
                            //If curve is horizontal,and in the middle range,log it
                            double cSz = curve.GetEndPoint(0).Z;
                            double cEz = curve.GetEndPoint(1).Z;
                            if ((Math.Abs(cSz - cEz) < er) && (cSz > levelF + er) && (cSz < levelC - er))
                            {
                                hoCrvs.Add(curve.CreateTransformed(correction));
                            }
                        }
                    }

                    #region Sort pts according to curve direction
                    var tempPts = from point in points
                                  where ((point.Z > levelF + er) && (point.Z < levelC - er))
                                  select new XYZ(point.X, point.Y, levelF);
                    List <XYZ> relayPts = tempPts.ToList <XYZ>();
                    relayPts.Add(start); relayPts.Add(end);
                    var sortPt = from point in relayPts
                                 where (segCrv.Distance(point) < er)
                                 orderby(point - start).GetLength()
                                 select point;
                    List <XYZ> sortPtList = sortPt
                                            .Distinct(new PtEqualComparer())
                                            .ToList <XYZ>();
                    if (!(sortPtList[0] == start))
                    {
                        sortPtList.Reverse();
                    }
                    sortPtList.RemoveAt(sortPtList.Count - 1);
                    sortPtList.RemoveAt(0);
                    #endregion

                    #region log the data
                    theSeg.crvList = hoCrvs;
                    theSeg.ptList  = sortPtList;
                    theSeg.normal  = normal;
                    #endregion

                    //Find insert element(and project on plane)
                    List <ElementId> insertIds = theWall
                                                 .FindInserts(true, true, true, true).Distinct().ToList();
                    foreach (ElementId eId in insertIds)
                    {
                        Element        currentRoom = doc.GetElement(eId);
                        BoundingBoxXYZ box         = currentRoom.get_Geometry(new Options()).GetBoundingBox();
                        XYZ            ept         = 0.5 * (box.Max + box.Min);
                        XYZ            v           = ept - plane.Origin;
                        double         signedDist  = plane.Normal.DotProduct(v);
                        XYZ            eptnew      = ept - signedDist * normal;
                        theSeg.insertPts.Add(eptnew);
                    }

                    //Push to the stack.
                    eSegments.Push(theSeg);
                }

                #region Merge from segments to walls...
                //Merge the segments that are on same curve.
                int         segNum = eSegments.Count;
                EdgeSegment sNew;
                for (int i = 1; i < segNum; i++)
                {
                    EdgeSegment s1 = eSegments.Pop();
                    EdgeSegment s2 = eSegments.Pop();
                    if (!(s2.MergeWith(s1, out sNew)))
                    {
                        eSegmentsMerged.Add(s1);
                    }
                    eSegments.Push(sNew);
                }

                //Compare the final one to the first one again
                EdgeSegment sf1 = eSegmentsMerged[0];
                EdgeSegment sf2 = eSegments.Pop();
                if (sf2.MergeWith(sf1, out sNew))
                {
                    eSegmentsMerged.RemoveAt(0);
                }
                eSegmentsMerged.Add(sNew);
                //Because the use of stack,the order need to be reversed back.
                eSegmentsMerged.Reverse();
                #endregion

                #region Set the offset for each corner according to dist2W
                int wallNum = eSegmentsMerged.Count;
                eSegmentsMerged.Add(eSegmentsMerged[0]);
                for (int i = 0; i < wallNum; i++)
                {
                    EdgeSegment SegCur = eSegmentsMerged[i];
                    EdgeSegment SegAft = eSegmentsMerged[i + 1];
                    double      angle  = SegCur.unitV.AngleOnPlaneTo(SegAft.unitV, XYZ.BasisZ);
                    SegCur.end   -= Math.Tan(0.5 * angle) * dist2W * SegCur.unitV;
                    SegAft.start += Math.Tan(0.5 * angle) *
                                    (dist2W + UnitUtils.ConvertToInternalUnits(10, DisplayUnitType.DUT_MILLIMETERS)) *
                                    SegAft.unitV;
                }
                eSegmentsMerged.RemoveAt(eSegmentsMerged.Count - 1);
                #endregion

                rSegments.AddRange(eSegmentsMerged);
            }

            return(rSegments);
        }
        private Reference GetWallSideFaceRef()
        {
            IList <Reference> wallSideFaceRefs = HostObjectUtils.GetSideFaces(Wall, ShellLayerType.Interior);

            return(wallSideFaceRefs[0]);
        }
            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);
        }
예제 #20
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;
            View          view  = doc.ActiveView;
            //TaskDialog.Show("Revit", "Hello World");

            // Create filters and collect walls/ slabs/ columns id in corresponding collector
            // walls
            IList <ElementId>        walls_id       = new List <ElementId>();
            FilteredElementCollector wall_collector = new FilteredElementCollector(doc).OfClass(typeof(Wall));

            foreach (Element w in wall_collector)
            {
                if (w is Wall)
                {
                    walls_id.Add(w.Id);
                }
            }
            // columns
            IList <ElementId>        columns_id       = new List <ElementId>();
            FilteredElementCollector column_collector = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_StructuralColumns);

            foreach (Element c in column_collector)
            {
                if (c is FamilyInstance)
                {
                    columns_id.Add(c.Id);
                }
            }
            // slabs
            IList <ElementId>        slabs_id  = new List <ElementId>();
            FilteredElementCollector collector = new FilteredElementCollector(doc).OfClass(typeof(Floor));

            foreach (Element e in collector)
            {
                if (e is Floor)
                {
                    slabs_id.Add(e.Id);
                }
            }

            //call create parts on walls/ slabs/ columns collectors
            using (Transaction t = new Transaction(doc, "Create Part")) {
                t.Start();
                // Create parts from the selected element
                // There is "CreateParts" but no "CreatePart", so needed to use a list containing the one element
                PartUtils.CreateParts(doc, walls_id);
                PartUtils.CreateParts(doc, columns_id);
                PartUtils.CreateParts(doc, slabs_id);
                t.Commit();
            }

            // start divide parts for walls, columns, slabs
            foreach (ElementId w_id in walls_id)
            {
                ICollection <ElementId> partsList = PartUtils.GetAssociatedParts(doc, w_id, true, true);

                // Get all levels
                ICollection <ElementId> levels = new FilteredElementCollector(doc).OfClass(typeof(Level)).OfCategory(BuiltInCategory.OST_Levels).ToElementIds();

                // Create a list of curves which needs to be used in DivideParts but for this example
                // the divide is being done by levels so the curve list will be empty
                IList <Curve> curve_list = new List <Curve>();

                // Get the host object corresponding to the selected element
                // HostObject is the parent class for walls, roof, floors, etc.
                HostObject hostObj = doc.GetElement(w_id) as HostObject;

                // Get the reference of one of the major faces of the selected element
                // Will be used to create a sketch plane
                Reference r = HostObjectUtils.GetSideFaces(hostObj, ShellLayerType.Exterior).First();

                using (Transaction t = new Transaction(doc, "Divide Part at Levels"))
                {
                    t.Start();
                    //Plane ref_plane = Plane.CreateByNormalAndOrigin(faceNormal, XYZ.Zero);
                    SketchPlane wall_sketchPlane = SketchPlane.Create(doc, r);
                    //SketchPlane sketchPlane = doc.Create.NewSketchPlane(r);
                    // Divide the parts
                    PartUtils.DivideParts(doc, partsList, levels, curve_list, wall_sketchPlane.Id);
                    t.Commit();
                }
            }

            // since walls and columns are all divided by all levels, so just use the sketch-plane of the last wall element
            ElementId borrow_from_wall = walls_id[0];

            foreach (ElementId c_id in columns_id)
            {
                ICollection <ElementId> partsList  = PartUtils.GetAssociatedParts(doc, c_id, true, true);
                ICollection <ElementId> levels     = new FilteredElementCollector(doc).OfClass(typeof(Level)).OfCategory(BuiltInCategory.OST_Levels).ToElementIds();
                IList <Curve>           curve_list = new List <Curve>();
                HostObject hostObj = doc.GetElement(borrow_from_wall) as HostObject;
                Reference  r       = HostObjectUtils.GetSideFaces(hostObj, ShellLayerType.Exterior).First();

                using (Transaction t = new Transaction(doc, "Divide Part at Levels")) {
                    t.Start();
                    SketchPlane column_sketchPlane = SketchPlane.Create(doc, r);
                    PartUtils.DivideParts(doc, partsList, levels, curve_list, column_sketchPlane.Id);
                    t.Commit();
                }
            }

            foreach (ElementId s_id in slabs_id)
            {
                //Selection sel = uidoc.Selection;
                //ISelectionFilter f = new JtElementsOfClassSelectionFilter<Grid>();
                //Reference elemRef = sel.PickObject(ObjectType.Element, f, "Pick a grid");
                //Grid grid = doc.GetElement(elemRef) as Grid;
                //ICollection<ElementId> grid_list = new List<ElementId>();
                //grid_list.Add(grid.Id);
                //IList<Curve> gridCurves = grid.GetCurvesInView(DatumExtentType.Model, view);

                ICollection <ElementId> partsList = PartUtils.GetAssociatedParts(doc, s_id, true, true);

                // Get all levels
                ICollection <ElementId> grids = new FilteredElementCollector(doc).OfClass(typeof(Grid)).OfCategory(BuiltInCategory.OST_Grids).ToElementIds();


                // Create a list of curves which needs to be used in DivideParts but for this example
                // the divide is being done by levels so the curve list will be empty
                IList <Curve> curve_list = new List <Curve>();

                HostObject hostObj = doc.GetElement(s_id) as HostObject;
                Reference  r       = HostObjectUtils.GetTopFaces(hostObj).First();
                using (Transaction t = new Transaction(doc, "Divide Part at Grids")) {
                    t.Start();
                    //Transaction sketchPlaneTransaction = new Transaction(doc, "Create Sketch Plane");
                    SketchPlane grid_sketchPlane = SketchPlane.Create(doc, r);
                    //SketchPlane grid_sketchPlane = null;
                    //sketchPlaneTransaction.Commit();
                    PartUtils.DivideParts(doc, partsList, grids, curve_list, grid_sketchPlane.Id);
                    t.Commit();
                }
            }
            // Set the view's "Parts Visibility" parameter so that parts are shown
            Parameter p = doc.ActiveView.get_Parameter(BuiltInParameter.VIEW_PARTS_VISIBILITY);

            using (Transaction t = new Transaction(doc, "Set View Parameter"))
            {
                t.Start();
                p.Set(0); // 0 = Show Parts, 1 = Show Original, 2 = Show Both
                t.Commit();
            }



            //ICollection<ElementId> elementIdsToDivide = new List<ElementId>();
            //if (PartUtils.AreElementsValidForCreateParts(doc, slabs_id))
            //{
            //    // AreElementsValidForCreateParts returned true, so the selected element is not a part but it is an element that can be used to create a part.
            //    Transaction createPartTransaction = new Transaction(doc, "Create Part");
            //    createPartTransaction.Start();
            //    PartUtils.CreateParts(doc, slabs_id); // create the parts
            //    createPartTransaction.Commit();
            //    foreach (ElementId e_id in slabs_id)
            //    {
            //        elementIdsToDivide = PartUtils.GetAssociatedParts(doc, e_id, true, true);
            //    }// get the id of the newly created part
            //}
            ////else if (pickedElement is Part)
            ////{
            ////    // The selected element is a part, so that part will be divided.
            ////    elementIdsToDivide.Add(pickedElement.Id);
            ////}
            //// Create geometry that will be used to divide the part. For this example, a new part will be divided from the main part that is one quarter of the face. More complex intelligence could be coded to divide the part based on construction logistics or the properties of the materials being used to create the part.
            //XYZ pointRight = null;
            //XYZ pointTop = null;
            //XYZ pointCorner = null;
            //XYZ pointCenter = null;

            //SketchPlane sketchPlane = null;
            //Plane plane = null;

            //Options opt = new Options();
            //opt.ComputeReferences = true;
            //foreach (Element e in slabs)
            //{
            //    GeometryElement geomElem = e.get_Geometry(opt);
            //    foreach (GeometryObject geomObject in geomElem)
            //    {
            //        if (geomObject is Solid) // get the solid geometry of the selected element
            //        {
            //            Solid solid = geomObject as Solid;
            //            FaceArray faceArray = solid.Faces;
            //            foreach (Face face in faceArray)
            //            {
            //                // find the center of the face
            //                BoundingBoxUV bbox = face.GetBoundingBox();
            //                UV center = new UV((bbox.Max.U - bbox.Min.U) / 2 + bbox.Min.U, (bbox.Max.V - bbox.Min.V) / 2 + bbox.Min.V);
            //                XYZ faceNormal = face.ComputeNormal(center);
            //                if (faceNormal.IsAlmostEqualTo(XYZ.BasisZ)) // this example is designed to work with a floor or other element with a large face whose normal is in the Z direction
            //                {
            //                    Transaction sketchPlaneTransaction = new Transaction(doc, "Create Sketch Plane");
            //                    sketchPlaneTransaction.Start();
            //                    plane = Plane.CreateByNormalAndOrigin(faceNormal, XYZ.Zero);
            //                    sketchPlane = SketchPlane.Create(doc, plane);
            //                    //sketchPlane = doc.SketchPlane.Create(face as PlanarFace);
            //                    sketchPlaneTransaction.Commit();

            //                    pointCenter = face.Evaluate(center);

            //                    UV top = new UV((bbox.Max.U - bbox.Min.U) / 2 + bbox.Min.U, bbox.Max.V);
            //                    pointTop = face.Evaluate(top);

            //                    UV right = new UV(bbox.Max.U, (bbox.Max.V - bbox.Min.V) / 2 + bbox.Min.V);
            //                    pointRight = face.Evaluate(right);

            //                    UV corner = new UV(bbox.Max.U, bbox.Max.V);
            //                    pointCorner = face.Evaluate(corner);

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

            ////Selection sel = uidoc.Selection;
            ////Reference elemRef = sel.PickObject(
            ////ObjectType.Element, f, "Pick a grid");
            ////Grid grid = doc.GetElement(elemRef) as Grid;

            //// Create the curves that will be used for the part division.
            //IList<Curve> curveList = new List<Curve>();
            ////Curve curve1 = app.Create.NewLine(pointCenter, pointRight, true);
            //Curve curve1 = Line.CreateBound(pointCenter, pointRight);
            //curveList.Add(curve1);
            ////Curve curve2 = app.Create.NewLine(pointRight, pointCorner, true);
            //Curve curve2 = Line.CreateBound(pointRight, pointCorner);
            //curveList.Add(curve2);
            ////Curve curve3 = app.Create.NewLine(pointCorner, pointTop, true);
            //Curve curve3 = Line.CreateBound(pointCorner, pointTop);
            //curveList.Add(curve3);
            ////Curve curve4 = app.Create.NewLine(pointTop, pointCenter, true);
            //Curve curve4 = Line.CreateBound(pointTop, pointCenter);
            //curveList.Add(curve4);

            //// intersectingReferenceIds will be empty for this example.
            //ICollection<ElementId> intersectingReferenceIds = new List<ElementId>();

            //// Divide the part
            //Transaction dividePartTransaction = new Transaction(doc, "Divide Part");
            //dividePartTransaction.Start();
            //PartMaker maker = PartUtils.DivideParts(doc, elementIdsToDivide, intersectingReferenceIds, curveList, sketchPlane.Id);
            //dividePartTransaction.Commit();
            ////ICollection<ElementId> divElems = maker.GetSourceElementIds(); // Get the ids of the divided elements

            //// Set the view's "Parts Visibility" parameter so that parts are shown
            //Parameter partVisInView = doc.ActiveView.get_Parameter(BuiltInParameter.VIEW_PARTS_VISIBILITY);
            //Transaction setPartVizTransaction = new Transaction(doc, "Set View Parameter");
            //setPartVizTransaction.Start();
            //partVisInView.Set(0); // 0 = Show Parts, 1 = Show Original, 2 = Show Both
            //setPartVizTransaction.Commit();
            ////// Access current selection



            return(Result.Succeeded);
        }
예제 #21
0
 public static List<Face> GetWallSideFace(Wall wall, bool isOuterFace)
 {
     var refs = HostObjectUtils.GetSideFaces(wall, isOuterFace ? ShellLayerType.Exterior : ShellLayerType.Interior);
     return refs.Select(rf => wall.GetGeometryObjectFromReference(rf) as Face).Where(obj => obj != null).ToList();
 }
예제 #22
0
        /// <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 ); // 2016
                        Plane plane = CurveLoop.CreateViaOffset(
                            curveLoop, 5 * normal.GetLength(),
                            normal.Normalize()).GetPlane(); // 2017

                        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);
        }
예제 #23
0
        public void InsertOpening(Document doc, FamilySymbol familySymbol)
        {
            Element host = doc.GetElement(HostId);

            if (host.Category.Id.IntegerValue == (int)BuiltInCategory.OST_Walls)
            {
                Wall      wall      = host as Wall;
                Reference reference = HostObjectUtils.GetSideFaces(wall, ShellLayerType.Exterior).First();
                ElementId levelId   = host.LevelId;

                Face face = host.GetGeometryObjectFromReference(reference) as Face;
                IntersectionResult intResult = face.Project(LocationPoint);
                if (intResult == null)
                {
                    return;                    // important to prompt user if no face found
                }
                double distance = intResult.Distance;
                if (distance > 0.001)
                {
                    reference = HostObjectUtils.GetSideFaces(wall, ShellLayerType.Interior).First();;
                }

                FamilyInstance fi        = doc.Create.NewFamilyInstance(reference, LocationPoint, new XYZ(0, 0, 0), familySymbol);
                Parameter      parameter = fi.get_Parameter(BuiltInParameter.INSTANCE_SCHEDULE_ONLY_LEVEL_PARAM);
                if (parameter != null)
                {
                    parameter.Set(levelId);
                }

                if (OpeningType == OpeningType.Round)
                {
                    fi.LookupParameter("D").Set(_cloudOpening.Diameter);
                    fi.LookupParameter("Cut Offset").Set(_cloudOpening.Offset);
                    fi.get_Parameter(new Guid("f417eece-19f0-4253-9820-f876661146e3")).Set(GtbPairGuid);
                }
                if (OpeningType == OpeningType.Rectangular)
                {
                    fi.LookupParameter("b").Set(_cloudOpening.Width);
                    fi.LookupParameter("h").Set(_cloudOpening.Height);
                    fi.LookupParameter("Cut Offset").Set(_cloudOpening.Offset);
                    fi.get_Parameter(new Guid("f417eece-19f0-4253-9820-f876661146e3")).Set(GtbPairGuid);
                }
                fi.LookupParameter("Depth").Set(Depth);
            }


            if (host.Category.Id.IntegerValue == (int)BuiltInCategory.OST_Floors)
            {
                Floor          floor     = host as Floor;
                Reference      reference = HostObjectUtils.GetTopFaces(floor).First();
                ElementId      levelId   = host.LevelId;
                FamilyInstance fi        = doc.Create.NewFamilyInstance(reference, LocationPoint, new XYZ(0, 0, 0), familySymbol);
                Parameter      parameter = fi.get_Parameter(BuiltInParameter.INSTANCE_SCHEDULE_ONLY_LEVEL_PARAM);
                if (parameter != null)
                {
                    parameter.Set(levelId);
                }

                if (OpeningType == OpeningType.Round)
                {
                    fi.LookupParameter("D").Set(_cloudOpening.Diameter);
                    fi.LookupParameter("Cut Offset").Set(_cloudOpening.Offset);
                    fi.get_Parameter(new Guid("f417eece-19f0-4253-9820-f876661146e3")).Set(GtbPairGuid);
                }
                if (OpeningType == OpeningType.Rectangular)
                {
                    fi.LookupParameter("b").Set(_cloudOpening.Width);
                    fi.LookupParameter("h").Set(_cloudOpening.Height);
                    fi.LookupParameter("Cut Offset").Set(_cloudOpening.Offset);
                    fi.get_Parameter(new Guid("f417eece-19f0-4253-9820-f876661146e3")).Set(GtbPairGuid);
                }
                fi.LookupParameter("Depth").Set(Depth);
            }


            if (host.Category.Id.IntegerValue == (int)BuiltInCategory.OST_Ceilings)
            {
                Ceiling        ceiling   = host as Ceiling;
                Reference      reference = HostObjectUtils.GetTopFaces(ceiling).First();
                ElementId      levelId   = host.LevelId;
                FamilyInstance fi        = doc.Create.NewFamilyInstance(reference, LocationPoint, new XYZ(0, 0, 0), familySymbol);
                Parameter      parameter = fi.get_Parameter(BuiltInParameter.INSTANCE_SCHEDULE_ONLY_LEVEL_PARAM);
                if (parameter != null)
                {
                    parameter.Set(levelId);
                }

                if (OpeningType == OpeningType.Round)
                {
                    fi.LookupParameter("D").Set(_cloudOpening.Diameter);
                    fi.LookupParameter("Cut Offset").Set(_cloudOpening.Offset);
                    fi.get_Parameter(new Guid("f417eece-19f0-4253-9820-f876661146e3")).Set(GtbPairGuid);
                }
                if (OpeningType == OpeningType.Rectangular)
                {
                    fi.LookupParameter("b").Set(_cloudOpening.Width);
                    fi.LookupParameter("h").Set(_cloudOpening.Height);
                    fi.LookupParameter("Cut Offset").Set(_cloudOpening.Offset);
                    fi.get_Parameter(new Guid("f417eece-19f0-4253-9820-f876661146e3")).Set(GtbPairGuid);
                }
                fi.LookupParameter("Depth").Set(_cloudOpening.Depth);
            }

            if (host.Category.Id.IntegerValue == (int)BuiltInCategory.OST_Roofs)
            {
                Reference        reference  = null;
                ExtrusionRoof    eRoof      = host as ExtrusionRoof;
                List <Reference> references = HostObjectUtils.GetTopFaces(eRoof).ToList();
                foreach (Reference r in references)
                {
                    Face face = host.GetGeometryObjectFromReference(r) as Face;
                    //bool test = face.IsInside(new UV(LocationPoint.X, LocationPoint.Y));
                    IntersectionResult intResult = face.Project(LocationPoint);
                    if (intResult == null)
                    {
                        continue;
                    }
                    double distance = intResult.Distance;
                    if (distance < 0.001)
                    {
                        reference = r;
                    }
                }
                if (reference == null)
                {
                    return;
                }

                ElementId      levelId   = host.LevelId;
                FamilyInstance fi        = doc.Create.NewFamilyInstance(reference, LocationPoint, new XYZ(0, 0, 0), familySymbol);
                Parameter      parameter = fi.get_Parameter(BuiltInParameter.INSTANCE_SCHEDULE_ONLY_LEVEL_PARAM);
                if (parameter != null)
                {
                    parameter.Set(levelId);
                }

                if (OpeningType == OpeningType.Round)
                {
                    fi.LookupParameter("D").Set(_cloudOpening.Diameter);
                    fi.LookupParameter("Cut Offset").Set(_cloudOpening.Offset);
                    fi.get_Parameter(new Guid("f417eece-19f0-4253-9820-f876661146e3")).Set(GtbPairGuid);
                }
                if (OpeningType == OpeningType.Rectangular)
                {
                    fi.LookupParameter("b").Set(_cloudOpening.Width);
                    fi.LookupParameter("h").Set(_cloudOpening.Height);
                    fi.LookupParameter("Cut Offset").Set(_cloudOpening.Offset);
                    fi.get_Parameter(new Guid("f417eece-19f0-4253-9820-f876661146e3")).Set(GtbPairGuid);
                }
                fi.LookupParameter("Depth").Set(_cloudOpening.Depth);
            }
        }
예제 #24
0
        public bool DoCreateSockets()
        {
            this.LoadSocketsFamilies(ActiveDoc);

            Document        doc        = this.ActiveDoc;
            List <A_Socket> allSockets =
                CurrentHouse.Floors
                .SelectMany(f => f.Socket)
                .ToList();
            List <A_Wall> allWalls =
                CurrentHouse.Floors
                .SelectMany(f => f.Walls)
                .ToList();

            if (allSockets.Count() == 0)
            {
                return(false);
            }

            foreach (A_Socket soc in allSockets)
            {
                XYZ centerPt = new XYZ
                                   (soc.X, soc.Y, soc.Z + BaseLevel.Elevation);
                XYZ dirPt = new XYZ
                                (0 - soc.Orientation.Y, soc.Orientation.X, 0);

                ///Get all the face of the host wall.
                Wall hostWall = allWalls
                                .First(w => w.Uid == soc.Related.Uid).Wall;

                List <Reference> sideFaces =
                    HostObjectUtils.GetSideFaces
                        (hostWall, ShellLayerType.Exterior)
                    .ToList();
                sideFaces.AddRange(
                    HostObjectUtils.GetSideFaces
                        (hostWall, ShellLayerType.Interior)
                    .ToList());

                ///Find the face where the socket is located.
                Reference hostFace = sideFaces
                                     .OrderBy(f => centerPt.DistanceTo
                                                  ((doc.GetElement(f)
                                                    .GetGeometryObjectFromReference(f)
                                                    as Face)
                                                  .Project(centerPt).XYZPoint))
                                     .First();
                if (hostFace == null)
                {
                    continue;
                }

                ///Choose the type.
                Family socFam;
                switch (soc.Tag)
                {
                case "五孔":
                    socFam = AutoSocketFamilies
                             .First(s =>
                                    (s.Name.Contains("五孔")) &&
                                    (!s.Name.Contains("防水")));
                    break;

                case "五孔防水":
                    socFam = AutoSocketFamilies
                             .First(s => s.Name.Contains("五孔防水"));
                    break;

                case "网络电视":
                    socFam = AutoSocketFamilies
                             .First(s => s.Name.Contains("网络电视"));
                    break;

                default:
                    socFam = AutoSocketFamilies
                             .First(s => s.Name.Contains(soc.Tag));
                    break;
                }
                FamilySymbol socSymbol =
                    doc.GetElement
                        (socFam.GetFamilySymbolIds().First())
                    as FamilySymbol;

                socSymbol.Activate();
                soc.Instance = doc.Create
                               .NewFamilyInstance
                                   (hostFace, centerPt, dirPt, socSymbol);

                ActiveForm.UpdateProgress(socketWorkLoad);
            }
            return(true);
        }