Ejemplo n.º 1
0
        /***************************************************/
        /****              Public methods               ****/
        /***************************************************/

        public static List <PolyCurve> Perimeter(this SpatialElement spatialElement, RevitSettings settings = null)
        {
            if (spatialElement == null)
            {
                return(null);
            }

            IList <IList <BoundarySegment> > boundarySegments = spatialElement.GetBoundarySegments(new SpatialElementBoundaryOptions());

            if (boundarySegments == null)
            {
                return(null);
            }

            List <PolyCurve> results = new List <PolyCurve>();

            foreach (IList <BoundarySegment> boundarySegmentList in boundarySegments)
            {
                if (boundarySegmentList == null)
                {
                    continue;
                }

                List <BH.oM.Geometry.ICurve> curves = new List <ICurve>();
                foreach (BoundarySegment boundarySegment in boundarySegmentList)
                {
                    curves.Add(boundarySegment.GetCurve().IFromRevit());
                }

                results.Add(BH.Engine.Geometry.Create.PolyCurve(curves));
            }

            return(results);
        }
Ejemplo n.º 2
0
        /// <summary>
        ///     Gets boundary curve list of the room.
        /// </summary>
        /// <param name="room"></param>
        /// <param name="opt"></param>
        /// <returns></returns>
        public static CurveLoop GetRoomProfile(this SpatialElement room, Option opt = null)
        {
            if (room is null)
            {
                throw new ArgumentNullException(nameof(room));
            }

            if (opt == null)
            {
                opt = new Option {
                    SpatialElementBoundaryLocation = Finish
                }
            }
            ;

            var segs = room.GetBoundarySegments(opt).SelectMany(s => s);

            var result = segs.Select(s => s.GetCurve()).ToCurveLoop();

            if (result.IsOpen())
            {
                throw new InvalidDataException("The profile isn't closed!");
            }

            return(result);
        }
Ejemplo n.º 3
0
 public void Stream(Type type)
 {
     if (MustStream(type))
     {
         _data.Add(new ObjectData("GetBoundarySegments", _spatialElement.GetBoundarySegments(_boundaryOptions)));
     }
 }
Ejemplo n.º 4
0
        private static void GetstructuralWallArea(Document doc, SpatialElement spElem, out double wallArea)
        {
            SpatialElementBoundaryOptions boundaryOptions =
                new SpatialElementBoundaryOptions
            {
                SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.Center
            };

            IList <IList <BoundarySegment> > bndSegmentsList =
                spElem.GetBoundarySegments(boundaryOptions);

            wallArea = 0;
            for (int i = 0; i < bndSegmentsList.Count; ++i)
            {
                for (int j = 0; j < bndSegmentsList[i].Count; ++j)
                {
                    Element boundaryElem = doc.GetElement(bndSegmentsList[i][j].ElementId);
                    if (boundaryElem is Wall &&
                        ((Wall)boundaryElem).get_Parameter(BuiltInParameter.WALL_STRUCTURAL_SIGNIFICANT).AsInteger() == 1)
                    {
                        Wall strWall = (Wall)boundaryElem;
                        wallArea += (strWall.WallType.Width / 2) *
                                    (bndSegmentsList[i][j].GetCurve().Length);
                    }
                }
            }
        }
 public void Stream(Type type)
 {
     if (MustStream(type))
     {
         data.Add(new Snoop.Data.Object("GetBoundarySegments", spatialElement.GetBoundarySegments(boundaryOptions)));
     }
 }
Ejemplo n.º 6
0
        /// <summary>
        ///     Gets the room's edge list.
        /// </summary>
        /// <param name="room"></param>
        /// <param name="boundary"></param>
        /// <returns></returns>
        public static List <Line> GetEdgeList(this SpatialElement room, SpatialElementBoundaryLocation boundary)
        {
            if (room == null)
            {
                throw new ArgumentNullException(nameof(room));
            }

            var result = new List <Line>();
            var opt    = new SpatialElementBoundaryOptions
            {
                StoreFreeBoundaryFaces         = true,
                SpatialElementBoundaryLocation = boundary
            };
            var segments = room.GetBoundarySegments(opt).SelectMany(s => s);

            foreach (var seg in segments)
            {
                var sp = seg.GetCurve().GetEndPoint(0);
                var ep = seg.GetCurve().GetEndPoint(1);

                result.Add(Line.CreateBound(sp, ep));
            }

            return(result);
        }
Ejemplo n.º 7
0
        public static List <List <RoomEdge> > GetRoomEdges(Document doc, SpatialElement room)
        {
            //Extract the boundary curves for a room based on the center of the enclosing element
            SpatialElementBoundaryOptions opt = new SpatialElementBoundaryOptions();

            opt.SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.Center;
            IList <IList <BoundarySegment> > boundarySegments = room.GetBoundarySegments(opt);
            List <List <RoomEdge> >          allRoomEdges     = new List <List <RoomEdge> >();

            foreach (List <BoundarySegment> l1 in boundarySegments)
            {
                List <RoomEdge> roomEdges = new List <RoomEdge>();
                foreach (BoundarySegment l2 in l1)
                {
                    RoomEdge roomEdge = new RoomEdge()
                    {
                        _Edge       = l2.GetCurve(),
                        _StartPoint = l2.GetCurve().GetEndPoint(0),
                    };
                    roomEdges.Add(roomEdge);
                }
                allRoomEdges.Add(roomEdges);
            }

            return(allRoomEdges);
        }
Ejemplo n.º 8
0
        static public List <List <Curve> > GetCurvesListFromSpatialElement(SpatialElement spatial)
        {
            List <List <Curve> >             profiles   = new List <List <Curve> >();
            SpatialElementBoundaryOptions    opt        = new SpatialElementBoundaryOptions();
            IList <IList <BoundarySegment> > boundaries = spatial.GetBoundarySegments(opt);

            for (int i = 0; i < boundaries.Count; i++)
            {
                profiles.Add(new List <Curve>());
                foreach (BoundarySegment s in boundaries[i])
                {
                    profiles[i].Add(s.GetCurve());
                }
            }
            return(profiles);
        }
Ejemplo n.º 9
0
        /// <summary>
        ///     Gets boundary wall list of the room.
        /// </summary>
        /// <param name="room"></param>
        /// <param name="doc"></param>
        /// <param name="opt"></param>
        /// <returns></returns>
        public static List <Wall> GetBoundaryWallList(this SpatialElement room, Document doc, Option opt = null)
        {
            if (room is null)
            {
                throw new ArgumentNullException(nameof(room));
            }

            if (doc is null)
            {
                throw new ArgumentNullException(nameof(doc));
            }

            var results = new List <Wall>();

            if (opt == null)
            {
                opt = new Option {
                    SpatialElementBoundaryLocation = Finish
                }
            }
            ;

            var segments = room.GetBoundarySegments(opt).SelectMany(s => s);

            foreach (var segment in segments)
            {
                // It's invalid!
                if (segment.ElementId.IntegerValue == -1)
                {
                    continue;
                }

                // Because base room boundary to do, so one wall maybe be picked up some times.
                if (results.FirstOrDefault(f => f.Id == segment.ElementId) != null)
                {
                    continue;
                }

                if (doc.GetElement(segment.ElementId) is Wall wall)
                {
                    results.Add(wall);
                }
            }

            return(results);
        }
    }
Ejemplo n.º 10
0
        public static Polygon RoomBoundary(Document doc, Reference re, Transform ttr)
        {
            SpatialElement se = doc.GetElement(re) as SpatialElement;

            SpatialElementBoundaryOptions opt = new SpatialElementBoundaryOptions();

            IList <IList <BoundarySegment> > loops = se.GetBoundarySegments(opt);

            List <IPosition> positions = new List <IPosition>();


            foreach (IList <BoundarySegment> loop in loops)
            {
                ElementId segId = new ElementId(123456);

                foreach (BoundarySegment seg in loop)
                {
                    Line segLine = seg.GetCurve() as Line;

                    XYZ endPt = segLine.Origin;

                    XYZ p = ttr.OfPoint(endPt);

                    Position firstpos = new Position(p.Y, p.X, p.Z);


                    if (segId == seg.ElementId)
                    {
                    }
                    else
                    {
                        positions.Add(new Position(p.Y, p.X, p.Z));
                    }

                    positions.Add(firstpos);

                    segId = seg.ElementId;
                }
            }

            return(new Polygon(new List <LineString> {
                new LineString(positions)
            }));
        }
Ejemplo n.º 11
0
        /// <summary>
        ///     Gets boundary wall list of the room.
        /// </summary>
        /// <param name="room"></param>
        /// <param name="doc"></param>
        /// <param name="maxThickness"></param>
        /// <returns></returns>
        public static List <Wall> GetBoundaryWallList(this SpatialElement room, Document doc, double maxThickness = 80)
        {
            if (room == null)
            {
                throw new ArgumentNullException(nameof(room));
            }

            if (doc == null)
            {
                throw new ArgumentNullException(nameof(doc));
            }

            const BuiltInParameter parmEnum = BuiltInParameter.WALL_ATTR_WIDTH_PARAM;
            var results = new List <Wall>();
            var loops   = room.GetBoundarySegments(new SpatialElementBoundaryOptions());

            foreach (var loop in loops)
            {
                foreach (var segment in loop)
                {
                    // It's invalid!
                    if (segment.ElementId.IntegerValue == -1)
                    {
                        continue;
                    }

                    // Because base room boundary to do, so one wall maybe be picked up some times.
                    if (results.FirstOrDefault(f => f.Id == segment.ElementId) != null)
                    {
                        continue;
                    }

                    if (doc.GetElement(segment.ElementId) is Wall wall)
                    {
                        results.Add(wall);
                    }
                }
            }

            return(results
                   .Where(w => Convert.ToDouble(w.WallType.get_Parameter(parmEnum).AsValueString()) < maxThickness)
                   .ToList());
        }
Ejemplo n.º 12
0
        public static List <ElementId> collectwindows(Document doc, Room room, List <ElementId> listfenid)
        {
            SpatialElementBoundaryOptions options = new SpatialElementBoundaryOptions();
            SpatialElement piece   = room as SpatialElement;
            BoundingBoxXYZ bbpiece = piece.get_BoundingBox(null);
            IList <IList <BoundarySegment> > contourpiece = piece.GetBoundarySegments(options);
            Outline outroom = new Outline(new XYZ(bbpiece.Min.X, bbpiece.Min.Y, bbpiece.Min.Z), new XYZ(bbpiece.Max.X, bbpiece.Max.Y, bbpiece.Max.Z));
            BoundingBoxIntersectsFilter bbfilter = new BoundingBoxIntersectsFilter(outroom);
            FilteredElementCollector    windows  = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Windows).WherePasses(bbfilter).WhereElementIsNotElementType();
            List <ElementId>            fenetres = windows.ToElementIds().ToList();

            foreach (ElementId fenid in listfenid)
            {
                if (fenetres.Contains(fenid))
                {
                    fenetres.Remove(fenid);
                }
            }
            return(fenetres);
        }
Ejemplo n.º 13
0
        public static List <Line> GetEdgeList(this SpatialElement room)
        {
            var result = new List <Line>();
            var option = new SpatialElementBoundaryOptions
            {
                StoreFreeBoundaryFaces         = true,
                SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.CoreBoundary
            };
            var segments = room.GetBoundarySegments(option).SelectMany(s => s);

            foreach (var seg in segments)
            {
                var sp = seg.GetCurve().GetEndPoint(0);
                var ep = seg.GetCurve().GetEndPoint(1);

                result.Add(Line.CreateBound(sp, ep));
            }

            return(result);
        }
Ejemplo n.º 14
0
        private static double GetRoomArea(SpatialElement spElem,
                                          SpatialElementBoundaryOptions boundaryOptions)
        {
            IList <IList <BoundarySegment> > bndSegmentsList =
                spElem.GetBoundarySegments(boundaryOptions);

            double grossArea = 0;

            for (int i = 0; i < bndSegmentsList.Count; ++i)
            {
                if (i == 0)
                {
                    grossArea += PolygonArea(bndSegmentsList[i]);
                }
                else
                {
                    grossArea -= PolygonArea(bndSegmentsList[i]);
                }
            }

            return(grossArea);
        }
        /// <summary>
        /// Exports spatial elements, including rooms, areas and spaces. 1st level space boundaries.
        /// </summary>
        /// <param name="exporterIFC">
        /// The ExporterIFC object.
        /// </param>
        /// <param name="spatialElement">
        /// The spatial element.
        /// </param>
        /// <param name="productWrapper">
        /// The ProductWrapper.
        /// </param>
        public static void ExportSpatialElement(ExporterIFC exporterIFC, SpatialElement spatialElement, ProductWrapper productWrapper)
        {
            IFCFile file = exporterIFC.GetFile();
            using (IFCTransaction transaction = new IFCTransaction(file))
            {
                using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, spatialElement, null, null))
                {
                    SpatialElementGeometryResults spatialElemGeomResult = null;
                    if (!CreateIFCSpace(exporterIFC, spatialElement, productWrapper, setter, out spatialElemGeomResult))
                        return;

                    bool isArea = (spatialElement is Area);

                    // Do not create boundary information for areas.
                    if (!isArea && (ExporterCacheManager.ExportOptionsCache.SpaceBoundaryLevel == 1))
                    {
                        Document document = spatialElement.Document;
                        ElementId levelId = spatialElement.LevelId;
                        IFCLevelInfo levelInfo = exporterIFC.GetLevelInfo(levelId);
                  double baseHeightNonScaled = (levelInfo != null) ? levelInfo.Elevation : 0.0;

                        try
                        {
                            // This can throw an exception.  If it does, continue to export element without boundary information.
                            // We will re-use the previously generated value, if we have it.
                            // TODO: warn user.
                            if (spatialElemGeomResult == null)
                                spatialElemGeomResult = s_SpatialElementGeometryCalculator.CalculateSpatialElementGeometry(spatialElement);

                            Solid spatialElemGeomSolid = spatialElemGeomResult.GetGeometry();
                            FaceArray faces = spatialElemGeomSolid.Faces;
                            foreach (Face face in faces)
                            {
                                IList<SpatialElementBoundarySubface> spatialElemBoundarySubfaces = spatialElemGeomResult.GetBoundaryFaceInfo(face);
                                foreach (SpatialElementBoundarySubface spatialElemBSubface in spatialElemBoundarySubfaces)
                                {
                                    if (spatialElemBSubface.SubfaceType == SubfaceType.Side)
                                        continue;

                                    if (spatialElemBSubface.GetSubface() == null)
                                        continue;

                                    ElementId elemId = spatialElemBSubface.SpatialBoundaryElement.LinkInstanceId;
                                    if (elemId == ElementId.InvalidElementId)
                                    {
                                        elemId = spatialElemBSubface.SpatialBoundaryElement.HostElementId;
                                    }

                                    Element boundingElement = document.GetElement(elemId);
                                    if (boundingElement == null)
                                        continue;

                                    bool isObjectExt = CategoryUtil.IsElementExternal(boundingElement);

                                    IFCGeometryInfo info = IFCGeometryInfo.CreateSurfaceGeometryInfo(spatialElement.Document.Application.VertexTolerance);

                                    Face subFace = spatialElemBSubface.GetSubface();
                                    ExporterIFCUtils.CollectGeometryInfo(exporterIFC, info, subFace, XYZ.Zero, false);

                                    foreach (IFCAnyHandle surfaceHnd in info.GetSurfaces())
                                    {
                                        IFCAnyHandle connectionGeometry = IFCInstanceExporter.CreateConnectionSurfaceGeometry(file, surfaceHnd, null);

                                        SpaceBoundary spaceBoundary = new SpaceBoundary(spatialElement.Id, boundingElement.Id, setter.LevelId, connectionGeometry, IFCPhysicalOrVirtual.Physical,
                                            isObjectExt ? IFCInternalOrExternal.External : IFCInternalOrExternal.Internal);

                                        if (!ProcessIFCSpaceBoundary(exporterIFC, spaceBoundary, file))
                                            ExporterCacheManager.SpaceBoundaryCache.Add(spaceBoundary);
                                    }
                                }
                            }
                        }
                        catch
                        {
                        }

                        IList<IList<BoundarySegment>> roomBoundaries = spatialElement.GetBoundarySegments(GetSpatialElementBoundaryOptions(spatialElement));
                        double scaledRoomHeight = GetScaledHeight(spatialElement, levelId, levelInfo);
                        double unscaledHeight = UnitUtil.UnscaleLength(scaledRoomHeight);

                        Plane xyPlane = new Plane(XYZ.BasisZ, XYZ.Zero);

                        foreach (IList<BoundarySegment> roomBoundaryList in roomBoundaries)
                        {
                            foreach (BoundarySegment roomBoundary in roomBoundaryList)
                            {
                                Element boundingElement = roomBoundary.Element;

                                if (boundingElement == null)
                                    continue;

                                ElementId buildingElemId = boundingElement.Id;
                                Curve trimmedCurve = roomBoundary.Curve;

                                if (trimmedCurve == null)
                                    continue;

                                //trimmedCurve.Visibility = Visibility.Visible; readonly
                                IFCAnyHandle connectionGeometry = ExtrusionExporter.CreateConnectionSurfaceGeometry(
                                   exporterIFC, trimmedCurve, xyPlane, scaledRoomHeight, baseHeightNonScaled);

                                IFCPhysicalOrVirtual physOrVirt = IFCPhysicalOrVirtual.Physical;
                                if (boundingElement is CurveElement)
                                    physOrVirt = IFCPhysicalOrVirtual.Virtual;
                                else if (boundingElement is Autodesk.Revit.DB.Architecture.Room)
                                    physOrVirt = IFCPhysicalOrVirtual.NotDefined;

                                bool isObjectExt = CategoryUtil.IsElementExternal(boundingElement);
                                bool isObjectPhys = (physOrVirt == IFCPhysicalOrVirtual.Physical);

                                ElementId actualBuildingElemId = isObjectPhys ? buildingElemId : ElementId.InvalidElementId;

                                SpaceBoundary spaceBoundary = new SpaceBoundary(spatialElement.Id, actualBuildingElemId, setter.LevelId, !IFCAnyHandleUtil.IsNullOrHasNoValue(connectionGeometry) ? connectionGeometry : null,
                                    physOrVirt, isObjectExt ? IFCInternalOrExternal.External : IFCInternalOrExternal.Internal);

                                if (!ProcessIFCSpaceBoundary(exporterIFC, spaceBoundary, file))
                                    ExporterCacheManager.SpaceBoundaryCache.Add(spaceBoundary);

                                // try to add doors and windows for host objects if appropriate.
                                if (isObjectPhys && boundingElement is HostObject)
                                {
                                    HostObject hostObj = boundingElement as HostObject;
                                    HashSet<ElementId> elemIds = new HashSet<ElementId>();
                                    elemIds.UnionWith(hostObj.FindInserts(false, false, false, false));
                                    if (elemIds.Count == 0)
                                    {
                                        CurtainGridSet curtainGridSet = CurtainSystemExporter.GetCurtainGridSet(hostObj);
                                        if (curtainGridSet != null)
                                        {
                                            foreach (CurtainGrid curtainGrid in curtainGridSet)
                                                elemIds.UnionWith(CurtainSystemExporter.GetVisiblePanelsForGrid(curtainGrid));
                                        }
                                    }

                                    foreach (ElementId elemId in elemIds)
                                    {
                                        // we are going to do a simple bbox export, not complicated geometry.
                                        Element instElem = document.GetElement(elemId);
                                        if (instElem == null)
                                            continue;

                                        BoundingBoxXYZ instBBox = instElem.get_BoundingBox(null);
                                        if (instBBox == null)
                                            continue;

                                        // make copy of original trimmed curve.
                                        Curve instCurve = trimmedCurve.Clone();
                                        XYZ instOrig = instCurve.GetEndPoint(0);

                                        // make sure that the insert is on this level.
                                        if (instBBox.Max.Z < instOrig.Z)
                                            continue;
                                        if (instBBox.Min.Z > instOrig.Z + unscaledHeight)
                                            continue;

                                        double insHeight = Math.Min(instBBox.Max.Z, instOrig.Z + unscaledHeight) - Math.Max(instOrig.Z, instBBox.Min.Z);
                                        if (insHeight < (1.0 / (12.0 * 16.0)))
                                            continue;

                                        // move base curve to bottom of bbox.
                                        XYZ moveDir = new XYZ(0.0, 0.0, instBBox.Min.Z - instOrig.Z);
                                        Transform moveTrf = Transform.CreateTranslation(moveDir);
                                        instCurve = instCurve.CreateTransformed(moveTrf);

                                        bool isHorizOrVert = false;
                                        if (instCurve is Line)
                                        {
                                            Line instLine = instCurve as Line;
                                            XYZ lineDir = instLine.Direction;
                                            if (MathUtil.IsAlmostEqual(Math.Abs(lineDir.X), 1.0) || (MathUtil.IsAlmostEqual(Math.Abs(lineDir.Y), 1.0)))
                                                isHorizOrVert = true;
                                        }

                                        double[] parameters = new double[2];
                                        double[] origEndParams = new double[2];
                                        bool paramsSet = false;

                                        if (!isHorizOrVert)
                                        {
                                            FamilyInstance famInst = instElem as FamilyInstance;
                                            if (famInst == null)
                                                continue;

                                            ElementType elementType = document.GetElement(famInst.GetTypeId()) as ElementType;
                                            if (elementType == null)
                                                continue;

                                            BoundingBoxXYZ symBBox = elementType.get_BoundingBox(null);
                                            if (symBBox != null)
                                            {
                                                Curve symCurve = trimmedCurve.Clone();
                                                Transform trf = famInst.GetTransform();
                                                Transform invTrf = trf.Inverse;
                                                Curve trfCurve = symCurve.CreateTransformed(invTrf);
                                                parameters[0] = trfCurve.Project(symBBox.Min).Parameter;
                                                parameters[1] = trfCurve.Project(symBBox.Max).Parameter;
                                                paramsSet = true;
                                            }
                                        }

                                        if (!paramsSet)
                                        {
                                            parameters[0] = instCurve.Project(instBBox.Min).Parameter;
                                            parameters[1] = instCurve.Project(instBBox.Max).Parameter;
                                        }

                                        // ignore if less than 1/16".
                                        if (Math.Abs(parameters[1] - parameters[0]) < 1.0 / (12.0 * 16.0))
                                            continue;
                                        if (parameters[0] > parameters[1])
                                        {
                                            //swap
                                            double tempParam = parameters[0];
                                            parameters[0] = parameters[1];
                                            parameters[1] = tempParam;
                                        }

                                        origEndParams[0] = instCurve.GetEndParameter(0);
                                        origEndParams[1] = instCurve.GetEndParameter(1);

                                        if (origEndParams[0] > parameters[1] - (1.0 / (12.0 * 16.0)))
                                            continue;
                                        if (origEndParams[1] < parameters[0] + (1.0 / (12.0 * 16.0)))
                                            continue;

                                        instCurve.MakeBound(parameters[0] > origEndParams[0] ? parameters[0] : origEndParams[0],
                                                            parameters[1] < origEndParams[1] ? parameters[1] : origEndParams[1]);

                                        double insHeightScaled = UnitUtil.ScaleLength(insHeight);
                                        IFCAnyHandle insConnectionGeom = ExtrusionExporter.CreateConnectionSurfaceGeometry(exporterIFC, instCurve, xyPlane,
                                           insHeightScaled, baseHeightNonScaled);

                                        SpaceBoundary instBoundary = new SpaceBoundary(spatialElement.Id, elemId, setter.LevelId, !IFCAnyHandleUtil.IsNullOrHasNoValue(insConnectionGeom) ? insConnectionGeom : null, physOrVirt,
                                            isObjectExt ? IFCInternalOrExternal.External : IFCInternalOrExternal.Internal);
                                        if (!ProcessIFCSpaceBoundary(exporterIFC, instBoundary, file))
                                            ExporterCacheManager.SpaceBoundaryCache.Add(instBoundary);
                                    }
                                }
                            }
                        }
                    }

                    CreateZoneInfos(exporterIFC, file, spatialElement, productWrapper);
                    CreateSpaceOccupantInfo(exporterIFC, file, spatialElement, productWrapper);
                }
                transaction.Commit();
            }
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Retrieve spatial element boundaries
        /// </summary>
        /// <param name="spaEl"></param>
        /// <returns></returns>
        public static IList <IList <BoundarySegment> > SpatialBoundaries(SpatialElement spaEl)
        {
            var boundaries = spaEl.GetBoundarySegments(new SpatialElementBoundaryOptions());

            return(boundaries);
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Gets Wall Panels from Spatial Element base on its Boundary
        /// </summary>
        /// <param name="spatialElement">Revit Spatial Element such as Space or Room</param>
        /// <param name="elevation_Bottom">Bottom Elevation</param>
        /// <param name="elevation_Top">Top Elevation</param>
        /// <param name="convertSettings">Convert Settings</param>
        /// <param name="spatialElementBoundaryOptions">Revit SpactialElementBoundaryOptions. Center Spatial Element Boundary Location will be used when set to null</param>
        /// <returns>Wall Panels</returns>
        public static List <Panel> Panels(this SpatialElement spatialElement, double elevation_Bottom, double elevation_Top, Core.Revit.ConvertSettings convertSettings, SpatialElementBoundaryOptions spatialElementBoundaryOptions = null)
        {
            if (spatialElement == null || double.IsNaN(elevation_Top) || double.IsNaN(elevation_Bottom))
            {
                return(null);
            }

            if (spatialElementBoundaryOptions == null)
            {
                spatialElementBoundaryOptions = new SpatialElementBoundaryOptions();
                spatialElementBoundaryOptions.SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.Center;
            }

            Document document = spatialElement.Document;

            Geometry.Spatial.Plane plane        = Geometry.Spatial.Plane.WorldXY;
            Geometry.Spatial.Plane plane_Top    = plane.GetMoved(new Geometry.Spatial.Vector3D(0, 0, elevation_Top)) as Geometry.Spatial.Plane;
            Geometry.Spatial.Plane plane_Bottom = plane.GetMoved(new Geometry.Spatial.Vector3D(0, 0, elevation_Bottom)) as Geometry.Spatial.Plane;

            List <Panel> panels = new List <Panel>();

            IList <IList <BoundarySegment> > boundaries = spatialElement.GetBoundarySegments(spatialElementBoundaryOptions);

            foreach (IList <BoundarySegment> boundarySegments in boundaries)
            {
                if (boundarySegments == null)
                {
                    continue;
                }

                foreach (BoundarySegment boundarySegment in boundarySegments)
                {
                    if (boundarySegment == null)
                    {
                        continue;
                    }

                    Curve curve = boundarySegment.GetCurve();
                    if (curve == null)
                    {
                        continue;
                    }

                    HostObject hostObject = null;
                    if (boundarySegment.ElementId != null && boundarySegment.ElementId != ElementId.InvalidElementId)
                    {
                        if (boundarySegment.LinkElementId == null || boundarySegment.LinkElementId == ElementId.InvalidElementId)
                        {
                            hostObject = document.GetElement(boundarySegment.ElementId) as HostObject;
                        }
                        else
                        {
                            RevitLinkInstance revitLinkInstance = document.GetElement(boundarySegment.LinkElementId) as RevitLinkInstance;
                            if (revitLinkInstance != null)
                            {
                                Document document_Linked = revitLinkInstance.GetLinkDocument();
                                if (document_Linked != null)
                                {
                                    hostObject = document_Linked.GetElement(boundarySegment.ElementId) as HostObject;
                                }
                            }
                        }
                    }

                    Panel panel_Temp = null;

                    if (hostObject != null)
                    {
                        List <Panel> panels_Temp = hostObject.ToSAM(convertSettings);
                        if (panels_Temp != null && panels_Temp.Count > 0)
                        {
                            panel_Temp = panels_Temp[0];
                        }
                    }

                    List <Geometry.Spatial.Segment3D> segment3Ds = Geometry.Revit.Convert.ToSAM_Segment3Ds(curve);
                    if (segment3Ds == null || segment3Ds.Count == 0)
                    {
                        continue;
                    }

                    foreach (Geometry.Spatial.Segment3D segment3D in segment3Ds)
                    {
                        Geometry.Spatial.Segment3D segment3D_Top    = Geometry.Spatial.Query.Project(plane_Top, segment3D);
                        Geometry.Spatial.Segment3D segment3D_Bottom = Geometry.Spatial.Query.Project(plane_Bottom, segment3D);

                        Geometry.Spatial.Polygon3D polygon3D = Geometry.Spatial.Create.Polygon3D(new Geometry.Spatial.Point3D[] { segment3D_Top[0], segment3D_Top[1], segment3D_Bottom[1], segment3D_Bottom[0] });
                        if (polygon3D == null)
                        {
                            continue;
                        }

                        Geometry.Spatial.Face3D face3D = new Geometry.Spatial.Face3D(polygon3D);

                        Panel panel = null;
                        if (panel_Temp != null)
                        {
                            panel = Analytical.Create.Panel(Guid.NewGuid(), panel_Temp, face3D);
                        }

                        if (panel_Temp != null)
                        {
                            Geometry.Spatial.Vector3D normal = polygon3D.GetPlane()?.Normal;
                            PanelType panelType = Analytical.Query.PanelType(normal);

                            Construction construction = Query.DefaultAirConstruction(panelType.PanelGroup());
                            panel = Analytical.Create.Panel(construction, panelType, face3D);
                        }

                        if (panel != null)
                        {
                            panels.Add(panel);
                        }
                    }
                }
            }

            return(panels);
        }
        /// <summary>
        /// Export spatial elements, including rooms, areas and spaces. 1st level space boundaries.
        /// </summary>
        /// <param name="exporterIFC">
        /// The ExporterIFC object.
        /// </param>
        /// <param name="spatialElement">
        /// The spatial element.
        /// </param>
        /// <param name="productWrapper">
        /// The IFCProductWrapper.
        /// </param>
        public static void ExportSpatialElement(ExporterIFC exporterIFC, SpatialElement spatialElement, IFCProductWrapper productWrapper)
        {
            //quick reject
            bool isArea = spatialElement is Area;
            if (isArea)
            {
                if (!IsAreaGrossInterior(exporterIFC, spatialElement))
                    return;
            }

            IFCFile file = exporterIFC.GetFile();
            using (IFCTransaction tr = new IFCTransaction(file))
            {
                ElementId levelId = spatialElement.Level != null ? spatialElement.Level.Id : ElementId.InvalidElementId;
                using (IFCPlacementSetter setter = IFCPlacementSetter.Create(exporterIFC, spatialElement, null, null, levelId))
                {
                    CreateIFCSpace(exporterIFC, spatialElement, productWrapper, setter);

                    // Do not create boundary information, or extra property sets.
                    if (spatialElement is Area)
                    {
                        tr.Commit();
                        return;
                    }

                    if (exporterIFC.SpaceBoundaryLevel == 1)
                    {
                        Document document = spatialElement.Document;
                        IFCLevelInfo levelInfo = exporterIFC.GetLevelInfo(levelId);
                        double baseHeightNonScaled = levelInfo.Elevation;

                        SpatialElementGeometryResults spatialElemGeomResult = s_SpatialElemGeometryCalculator.CalculateSpatialElementGeometry(spatialElement);

                        Solid spatialElemGeomSolid = spatialElemGeomResult.GetGeometry();
                        FaceArray faces = spatialElemGeomSolid.Faces;
                        foreach (Face face in faces)
                        {
                            IList<SpatialElementBoundarySubface> spatialElemBoundarySubfaces = spatialElemGeomResult.GetBoundaryFaceInfo(face);
                            foreach (SpatialElementBoundarySubface spatialElemBSubface in spatialElemBoundarySubfaces)
                            {
                                if (spatialElemBSubface.SubfaceType == SubfaceType.Side)
                                    continue;

                                if (spatialElemBSubface.GetSubface() == null)
                                    continue;

                                ElementId elemId = spatialElemBSubface.SpatialBoundaryElement.LinkInstanceId;
                                if (elemId == ElementId.InvalidElementId)
                                {
                                    elemId = spatialElemBSubface.SpatialBoundaryElement.HostElementId;
                                }

                                Element boundingElement = document.get_Element(elemId);
                                if (boundingElement == null)
                                    continue;

                                bool isObjectExt = CategoryUtil.IsElementExternal(boundingElement);

                                IFCGeometryInfo info = IFCGeometryInfo.CreateSurfaceGeometryInfo(spatialElement.Document.Application.VertexTolerance);

                                Face subFace = spatialElemBSubface.GetSubface();
                                ExporterIFCUtils.CollectGeometryInfo(exporterIFC, info, subFace, XYZ.Zero, false);

                                IFCAnyHandle ifcOptionalHnd = IFCAnyHandle.Create();
                                foreach (IFCAnyHandle surfaceHnd in info.GetSurfaces())
                                {
                                    IFCAnyHandle connectionGeometry = file.CreateConnectionSurfaceGeometry(surfaceHnd, ifcOptionalHnd);

                                    IFCSpaceBoundary spaceBoundary = IFCSpaceBoundary.Create(spatialElement.Id, boundingElement.Id, connectionGeometry, IFCSpaceBoundaryType.Physical, isObjectExt);

                                    if (!ProcessIFCSpaceBoundary(exporterIFC, spaceBoundary, file))
                                        exporterIFC.RegisterIFCSpaceBoundary(spaceBoundary);
                                }
                            }
                        }

                        IList<IList<BoundarySegment>> roomBoundaries = spatialElement.GetBoundarySegments(ExporterIFCUtils.GetSpatialElementBoundaryOptions(exporterIFC, spatialElement));
                        double roomHeight = GetHeight(spatialElement, exporterIFC.LinearScale, levelInfo);
                        XYZ zDir = new XYZ(0, 0, 1);

                        foreach (IList<BoundarySegment> roomBoundaryList in roomBoundaries)
                        {
                            foreach (BoundarySegment roomBoundary in roomBoundaryList)
                            {
                                Element boundingElement = roomBoundary.Element;

                                if (boundingElement == null)
                                    continue;

                                ElementId buildingElemId = boundingElement.Id;
                                Curve trimmedCurve = roomBoundary.Curve;

                                if (trimmedCurve == null)
                                    continue;

                                //trimmedCurve.Visibility = Visibility.Visible; readonly
                                IFCAnyHandle connectionGeometry = ExporterIFCUtils.CreateExtrudedSurfaceFromCurve(
                                   exporterIFC, trimmedCurve, zDir, roomHeight, baseHeightNonScaled);

                                IFCSpaceBoundaryType physOrVirt = IFCSpaceBoundaryType.Physical;
                                if (boundingElement is CurveElement)
                                    physOrVirt = IFCSpaceBoundaryType.Virtual;
                                else if (boundingElement is Autodesk.Revit.DB.Architecture.Room)
                                    physOrVirt = IFCSpaceBoundaryType.Undefined;

                                bool isObjectExt = CategoryUtil.IsElementExternal(boundingElement);
                                bool isObjectPhys = (physOrVirt == IFCSpaceBoundaryType.Physical);

                                ElementId actualBuildingElemId = isObjectPhys ? buildingElemId : ElementId.InvalidElementId;
                                IFCSpaceBoundary boundary = IFCSpaceBoundary.Create(spatialElement.Id, actualBuildingElemId, connectionGeometry, physOrVirt, isObjectExt);

                                if (!ProcessIFCSpaceBoundary(exporterIFC, boundary, file))
                                    exporterIFC.RegisterIFCSpaceBoundary(boundary);

                                // try to add doors and windows for host objects if appropriate.
                                if (isObjectPhys && boundingElement is HostObject)
                                {
                                    HostObject hostObj = boundingElement as HostObject;
                                    IList<ElementId> elemIds = hostObj.FindInserts(false, false, false, false);
                                    foreach (ElementId elemId in elemIds)
                                    {
                                        // we are going to do a simple bbox export, not complicated geometry.
                                        Element instElem = document.get_Element(elemId);
                                        if (instElem == null)
                                            continue;

                                        BoundingBoxXYZ instBBox = instElem.get_BoundingBox(null);

                                        // make copy of original trimmed curve.
                                        Curve instCurve = trimmedCurve.Clone();
                                        XYZ instOrig = instCurve.get_EndPoint(0);

                                        // make sure that the insert is on this level.
                                        if (instBBox.Max.Z < instOrig.Z)
                                            continue;
                                        if (instBBox.Min.Z > instOrig.Z + roomHeight)
                                            continue;

                                        double insHeight = Math.Min(instBBox.Max.Z, instOrig.Z + roomHeight) - Math.Max(instOrig.Z, instBBox.Min.Z);
                                        if (insHeight < (1.0 / (12.0 * 16.0)))
                                            continue;

                                        // move base curve to bottom of bbox.
                                        XYZ moveDir = new XYZ(0.0, 0.0, instBBox.Min.Z - instOrig.Z);
                                        Transform moveTrf = Transform.get_Translation(moveDir);
                                        instCurve = instCurve.get_Transformed(moveTrf);

                                        bool isHorizOrVert = false;
                                        if (instCurve is Line)
                                        {
                                            Line instLine = instCurve as Line;
                                            XYZ lineDir = instLine.Direction;
                                            if (MathUtil.IsAlmostEqual(Math.Abs(lineDir.X), 1.0) || (MathUtil.IsAlmostEqual(Math.Abs(lineDir.Y), 1.0)))
                                                isHorizOrVert = true;
                                        }

                                        double[] parameters = new double[2];
                                        double[] origEndParams = new double[2];
                                        if (isHorizOrVert)
                                        {
                                            parameters[0] = instCurve.Project(instBBox.Min).Parameter;
                                            parameters[1] = instCurve.Project(instBBox.Max).Parameter;
                                        }
                                        else
                                        {
                                            FamilyInstance famInst = instElem as FamilyInstance;
                                            if (famInst == null)
                                                continue;

                                            ElementType elementType = document.get_Element(famInst.GetTypeId()) as ElementType;
                                            if (elementType == null)
                                                continue;

                                            BoundingBoxXYZ symBBox = elementType.get_BoundingBox(null);
                                            Curve symCurve = trimmedCurve.Clone();
                                            Transform trf = famInst.GetTransform();
                                            Transform invTrf = trf.Inverse;
                                            Curve trfCurve = symCurve.get_Transformed(invTrf);
                                            parameters[0] = trfCurve.Project(symBBox.Min).Parameter;
                                            parameters[1] = trfCurve.Project(symBBox.Max).Parameter;
                                        }

                                        // ignore if less than 1/16".
                                        if (Math.Abs(parameters[1] - parameters[0]) < 1.0 / (12.0 * 16.0))
                                            continue;
                                        if (parameters[0] > parameters[1])
                                        {
                                            //swap
                                            double tempParam = parameters[0];
                                            parameters[0] = parameters[1];
                                            parameters[1] = tempParam;
                                        }

                                        origEndParams[0] = instCurve.get_EndParameter(0);
                                        origEndParams[1] = instCurve.get_EndParameter(1);

                                        if (origEndParams[0] > parameters[1] - (1.0 / (12.0 * 16.0)))
                                            continue;
                                        if (origEndParams[1] < parameters[0] + (1.0 / (12.0 * 16.0)))
                                            continue;

                                        if (parameters[0] > origEndParams[0])
                                            instCurve.set_EndParameter(0, parameters[0]);
                                        if (parameters[1] < origEndParams[1])
                                            instCurve.set_EndParameter(1, parameters[1]);

                                        IFCAnyHandle insConnectionGeom = ExporterIFCUtils.CreateExtrudedSurfaceFromCurve(exporterIFC, instCurve, zDir,
                                           insHeight, baseHeightNonScaled);

                                        IFCSpaceBoundary instBoundary = IFCSpaceBoundary.Create(spatialElement.Id, elemId, insConnectionGeom, physOrVirt, isObjectExt);
                                        if (!ProcessIFCSpaceBoundary(exporterIFC, instBoundary, file))
                                            exporterIFC.RegisterIFCSpaceBoundary(instBoundary);
                                    }
                                }
                            }
                        }
                    }
                    ExporterIFCUtils.CreateSpatialElementPropertySet(exporterIFC, spatialElement, productWrapper);
                }
                tr.Commit();
            }
        }
Ejemplo n.º 19
0
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            uiApp = commandData.Application;
            UIDocument uidoc = uiApp.ActiveUIDocument;

            doc = uidoc.Document;

            try
            {
                Transform ttr = doc.ActiveProjectLocation.GetTotalTransform().Inverse;
                Transform projectlocationTransform = GetProjectLocationTransform(doc);

                IList <Reference> roomReferences = uidoc.Selection.PickObjects(ObjectType.Element, "Select some rooms");

                SpatialElementBoundaryOptions opt = new SpatialElementBoundaryOptions();

                //control the boundary location
                opt.SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.Center;

                var features = new List <Feature>();

                foreach (Reference re in roomReferences)
                {
                    Element roomElement = doc.GetElement(re);

                    string roomName = "";
                    try
                    {
                        //roomName = roomElement.LookupParameter("Name").AsString();
                        roomName = roomElement.get_Parameter(BuiltInParameter.ROOM_NAME).AsString();
                    }
                    catch
                    {
                        TaskDialog.Show("Error", "Parameter \"Name\" not found in Room element");
                        return(Result.Failed);
                    }

                    SpatialElement se = doc.GetElement(re) as SpatialElement;

                    //multiPolygon.Add(Helpers.RoomBoundary(doc, re, ttr));

                    IList <IList <BoundarySegment> > loops = se.GetBoundarySegments(opt);

                    var featureProps = new Dictionary <string, object> {
                        { "Name", roomName }, { "Area", se.Area }
                    };

                    var coordinates = new List <Position>();

                    foreach (IList <BoundarySegment> loop in loops)
                    {
                        ElementId segId = new ElementId(123456);

                        foreach (BoundarySegment seg in loop)
                        {
                            Line segLine = seg.GetCurve() as Line;
                            XYZ  endPt   = segLine.GetEndPoint(0);

                            if (segId == seg.ElementId)
                            {
                            }
                            else
                            {
                                //TaskDialog.Show("re", $"{endPt.Y} {endPt.X}");
                                coordinates.Add(new Position(endPt.Y * 0.3048, endPt.X * 0.3048));
                            }

                            segId = seg.ElementId;
                        }
                    }

                    coordinates.Add(coordinates.First());

                    var polygon = new Polygon(new List <LineString> {
                        new LineString(coordinates)
                    });

                    features.Add(new Feature(polygon, featureProps));
                }


                var models = new FeatureCollection(features);



                #region File Export
                //EXPORT GEOJSON
                var          serializedData = JsonConvert.SerializeObject(models, Formatting.Indented);
                StreamWriter writetext      = new StreamWriter(@"C:\Temp\export.json");
                writetext.WriteLine(serializedData);
                writetext.Flush();
                writetext.Close();

                #endregion
                //Activate command in revit
                #region Revit Start Command
                Transaction trans = new Transaction(doc);
                trans.Start("GeoReader");
                trans.Commit();
                TaskDialog.Show("File was built", "Success");
                #endregion


                return(Result.Succeeded);
            }
            catch (Exception ex)
            {
                TaskDialog.Show("Error", ex.Message);
                return(Result.Failed);
            }
        }
Ejemplo n.º 20
0
        /// <summary>
        /// ethod to accept user input and close the window
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OK_Click(object sender, RoutedEventArgs e)
        {
            // Swap , for .
            string newStringNumber = this.offsetTextBox.Text.Replace(",", ".");

            bool isDouble = Double.TryParse(newStringNumber, out double number);

            if (isDouble)
            {
                // Retrieve project length unit
                DisplayUnitType dUT = Helpers.RevitProjectInfo.ProjectLengthUnit(doc);

                // Assign floor offset to property
                if (number != 0)
                {
                    FloorOffset = Helpers.UnitsConverter.LengthUnitToInternal(number, dUT);
                }
                else
                {
                    FloorOffset = 0;
                }

                // Retrieve all checked checkboxes
                IEnumerable <CheckBox> list = this.roomsCheckBoxes.Children.OfType <CheckBox>().Where(x => x.IsChecked == true);

                // SpatialElement boundary options
                SpatialElementBoundaryOptions sEBOpt = new SpatialElementBoundaryOptions();

                // Group transaction
                TransactionGroup tg = new TransactionGroup(doc, "Create Floor/s");
                tg.Start();

                // Add all checked checkboxes to global variable
                foreach (var x in list)
                {
                    SpatialElement sE = x.Tag as SpatialElement;

                    // Retrieve level
                    Level level = sE.Level;

                    // Store the floor created with first boundaries
                    Element floorElement = null;

                    // Retrieve boundaries of rooms
                    IList <IList <BoundarySegment> > boundaries = sE.GetBoundarySegments(sEBOpt);

                    // Retrieve boundaries and create floor and openings
                    for (int i = 0; i < boundaries.Count; i++)
                    {
                        if (boundaries[i].Count != 0 && i == 0)
                        {
                            // Floor boundary
                            CurveArray floorBoundary = new CurveArray();

                            foreach (var b in boundaries[i])
                            {
                                floorBoundary.Append(b.GetCurve());
                            }

                            // Create floor
                            Transaction transaction = new Transaction(doc, "Create Floor");
                            transaction.Start();

                            Floor floor = doc.Create.NewFloor(floorBoundary, SelectedComboItemFloorType.Tag as FloorType, level, false);
                            floorElement = floor as Element;

                            transaction.Commit();
                        }
                        // Create openings
                        else
                        {
                            // Opening boundary
                            CurveArray openingBoundary = new CurveArray();

                            foreach (var b in boundaries[i])
                            {
                                openingBoundary.Append(b.GetCurve());
                            }

                            if (floorElement != null)
                            {
                                // Create opening
                                Transaction transaction = new Transaction(doc, "Create Opening");
                                transaction.Start();

                                doc.Create.NewOpening(floorElement, openingBoundary, false);

                                transaction.Commit();
                            }
                        }
                    }

                    // Offset the floor
                    if (FloorOffset != 0)
                    {
                        // Move floor
                        Transaction transaction = new Transaction(doc, "Move floor");
                        transaction.Start();

                        ElementTransformUtils.MoveElement(doc, floorElement.Id, new XYZ(0, 0, FloorOffset));

                        transaction.Commit();
                    }
                }

                tg.Assimilate();

                this.Dispose();
            }
            else
            {
                Helpers.MessageWindows.AlertMessage("Error", "Please input a number for Offset from level.\n"
                                                    + "Use . or , only to separate decimal part.\n"
                                                    + "For example: 3.20 or 0,50");
            }
        }