示例#1
0
        /// <summary>
        /// Creates openings if there is necessary.
        /// </summary>
        /// <param name="elementHandle">The element handle to create openings.</param>
        /// <param name="element">The element to create openings.</param>
        /// <param name="info">The extrusion data.</param>
        /// <param name="extraParams">The extrusion creation data.</param>
        /// <param name="offsetTransform">The offset transform from ExportBody, or the identity transform.</param>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="originalPlacement">The original placement handle.</param>
        /// <param name="setter">The PlacementSetter.</param>
        /// <param name="wrapper">The ProductWrapper.</param>
        private static void CreateOpeningsIfNecessaryBase(IFCAnyHandle elementHandle, Element element, IList<IFCExtrusionData> info,
           IFCExtrusionCreationData extraParams, Transform offsetTransform, ExporterIFC exporterIFC,
           IFCAnyHandle originalPlacement, PlacementSetter setter, ProductWrapper wrapper)
        {
            if (IFCAnyHandleUtil.IsNullOrHasNoValue(elementHandle))
                return;

            int sz = info.Count;
            if (sz == 0)
                return;

            using (TransformSetter transformSetter = TransformSetter.Create())
            {
                if (offsetTransform != null)
                    transformSetter.Initialize(exporterIFC, offsetTransform.Inverse);

                IFCFile file = exporterIFC.GetFile();
                ElementId categoryId = CategoryUtil.GetSafeCategoryId(element);
                Document document = element.Document;

                string openingObjectType = "Opening";

                int openingNumber = 1;
                for (int curr = info.Count - 1; curr >= 0; curr--)
                {
                    IFCAnyHandle extrusionHandle = ExtrusionExporter.CreateExtrudedSolidFromExtrusionData(exporterIFC, element, info[curr]);
                    if (IFCAnyHandleUtil.IsNullOrHasNoValue(extrusionHandle))
                        continue;

                    IFCAnyHandle styledItemHnd = BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, document,
                        extrusionHandle, ElementId.InvalidElementId);

                    HashSet<IFCAnyHandle> bodyItems = new HashSet<IFCAnyHandle>();
                    bodyItems.Add(extrusionHandle);

                    IFCAnyHandle contextOfItems = exporterIFC.Get3DContextHandle("Body");
                    IFCAnyHandle bodyRep = RepresentationUtil.CreateSweptSolidRep(exporterIFC, element, categoryId, contextOfItems, bodyItems, null);
                    IList<IFCAnyHandle> representations = new List<IFCAnyHandle>();
                    representations.Add(bodyRep);

                    IFCAnyHandle openingRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, representations);

                    IFCAnyHandle openingPlacement = ExporterUtil.CopyLocalPlacement(file, originalPlacement);
                    string guid = GUIDUtil.CreateGUID();
                    IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle();
                    string openingName = NamingUtil.GetIFCNamePlusIndex(element, openingNumber++);
                    string elementId = NamingUtil.CreateIFCElementId(element);
                    IFCAnyHandle openingElement = IFCInstanceExporter.CreateOpeningElement(file, guid, ownerHistory,
                       openingName, null, openingObjectType, openingPlacement, openingRep, elementId);
                    wrapper.AddElement(null, openingElement, setter, extraParams, true);
                    if (ExporterCacheManager.ExportOptionsCache.ExportBaseQuantities && (extraParams != null))
                        PropertyUtil.CreateOpeningQuantities(exporterIFC, openingElement, extraParams);

                    string voidGuid = GUIDUtil.CreateGUID();
                    IFCInstanceExporter.CreateRelVoidsElement(file, voidGuid, ownerHistory, null, null, elementHandle, openingElement);
                }
            }
        }
        /// <summary>
        /// Export all the parts of the host element.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="hostElement">The host element having parts to export.</param>
        /// <param name="hostHandle">The host element handle.</param>
        /// <param name="originalWrapper">The ProductWrapper object.</param>
        public static void ExportHostPart(ExporterIFC exporterIFC, Element hostElement, IFCAnyHandle hostHandle,
            ProductWrapper originalWrapper, PlacementSetter placementSetter, IFCAnyHandle originalPlacement, ElementId overrideLevelId)
        {
            using (ProductWrapper subWrapper = ProductWrapper.Create(exporterIFC, true))
            {
                List<ElementId> associatedPartsList = PartUtils.GetAssociatedParts(hostElement.Document, hostElement.Id, false, true).ToList();
                if (associatedPartsList.Count == 0)
                    return;

                bool isWallOrColumn = IsHostWallOrColumn(exporterIFC, hostElement);
                bool hasOverrideLevel = overrideLevelId != null && overrideLevelId != ElementId.InvalidElementId;

                IFCExtrusionAxes ifcExtrusionAxes = GetDefaultExtrusionAxesForHost(exporterIFC, hostElement);

                // Split parts if wall or column is split by level, and then export; otherwise, export parts normally.
                if (isWallOrColumn && hasOverrideLevel && ExporterCacheManager.ExportOptionsCache.WallAndColumnSplitting)
                {
                    if (!ExporterCacheManager.HostPartsCache.HasRegistered(hostElement.Id))                
                        SplitParts(exporterIFC, hostElement, associatedPartsList); // Split parts and associate them with host.                   

                    // Find and export the parts that are split by specific level.
                    List<KeyValuePair<Part, IFCRange>> splitPartRangeList = new List<KeyValuePair<Part, IFCRange>>();
                    splitPartRangeList = ExporterCacheManager.HostPartsCache.Find(hostElement.Id, overrideLevelId);

                    foreach (KeyValuePair<Part, IFCRange> partRange in splitPartRangeList)
                    {
                        PartExporter.ExportPart(exporterIFC, partRange.Key, subWrapper, placementSetter, originalPlacement, partRange.Value, ifcExtrusionAxes, hostElement, overrideLevelId, false);
                    }
                }
                else
                {
                    foreach (ElementId partId in associatedPartsList)
                    {
                        Part part = hostElement.Document.GetElement(partId) as Part;
                        PartExporter.ExportPart(exporterIFC, part, subWrapper, placementSetter, originalPlacement, null, ifcExtrusionAxes, hostElement, overrideLevelId, false);
                    }
                }

                // Create the relationship of Host and Parts.
                ICollection<IFCAnyHandle> relatedElementIds = subWrapper.GetAllObjects();
                if (relatedElementIds.Count > 0)
                {
                    string guid = GUIDUtil.CreateGUID();
                    HashSet<IFCAnyHandle> relatedElementIdSet = new HashSet<IFCAnyHandle>(relatedElementIds);
                    IFCInstanceExporter.CreateRelAggregates(exporterIFC.GetFile(), guid, exporterIFC.GetOwnerHistoryHandle(), null, null, hostHandle, relatedElementIdSet);
                }
            }
        }
示例#3
0
        /// <summary>
        /// Adds openings to an element.
        /// </summary>
        /// <param name="exporterIFC">The exporter.</param>
        /// <param name="elementHandles">The parent handles.</param>
        /// <param name="curveLoops">The parent CurveLoops.</param>
        /// <param name="element">The element.</param>
        /// <param name="plane">The plane.</param>
        /// <param name="scaledWidth">The width.</param>
        /// <param name="range">The range.</param>
        /// <param name="setter">The placement setter.</param>
        /// <param name="localPlacement">The local placement.</param>
        /// <param name="localWrapper">The wrapper.</param>
        public static void AddOpeningsToElement(ExporterIFC exporterIFC, IList<IFCAnyHandle> elementHandles, IList<CurveLoop> curveLoops, Element element, Plane plane, double scaledWidth,
            IFCRange range, PlacementSetter setter, IFCAnyHandle localPlacement, ProductWrapper localWrapper)
        {
            IList<IFCOpeningData> openingDataList = ExporterIFCUtils.GetOpeningData(exporterIFC, element, plane, range);
            IFCFile file = exporterIFC.GetFile();
            IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle();
            foreach (IFCOpeningData openingData in openingDataList)
            {
                Element openingElem = element.Document.GetElement(openingData.OpeningElementId);
                if (openingElem == null)
                    openingElem = element;

                // Don't export the opening if WallSweep category has been turned off.
                // This is currently restricted to WallSweeps because the element responsible for the opening could be a variety of things, including a line as part of the elevation profile of the wall.
                // As such, we will restrict which element types we check for CanExportElement.
                if ((openingElem is WallSweep) && (!ElementFilteringUtil.CanExportElement(exporterIFC, openingElem, true)))
                    continue;

                IList<IFCExtrusionData> extrusionDataList = openingData.GetExtrusionData();
                IFCAnyHandle parentHandle = null;
                if (elementHandles.Count > 1 && extrusionDataList.Count > 0)
                {
                    parentHandle = FindParentHandle(elementHandles, curveLoops, extrusionDataList[0].GetLoops()[0]);
                }

                if (parentHandle == null)
                    parentHandle = elementHandles[0];

                bool isDoorOrWindowOpening = IsDoorOrWindowOpening(exporterIFC, openingElem, element);
                if (isDoorOrWindowOpening)
                {
                    DoorWindowDelayedOpeningCreator delayedCreator = 
                        DoorWindowDelayedOpeningCreator.Create(exporterIFC, openingData, scaledWidth, element.Id, parentHandle, setter.LevelId);
                    if (delayedCreator != null)
                    {
                        ExporterCacheManager.DoorWindowDelayedOpeningCreatorCache.Add(delayedCreator);
                        continue;
                    }
                }

                bool canUseElementGUID = !isDoorOrWindowOpening;

                IList<Solid> solids = openingData.GetOpeningSolids();
                foreach (Solid solid in solids)
                {
                    using (IFCExtrusionCreationData extrusionCreationData = new IFCExtrusionCreationData())
                    {
                        extrusionCreationData.SetLocalPlacement(ExporterUtil.CreateLocalPlacement(file, localPlacement, null));
                        extrusionCreationData.ReuseLocalPlacement = true;

                        string openingGUID = null;
                        if (canUseElementGUID)
                        {
                            openingGUID = GUIDUtil.CreateGUID(openingElem);
                            canUseElementGUID = false;
                        }
                        else
                            openingGUID = GUIDUtil.CreateGUID();
                        CreateOpening(exporterIFC, parentHandle, element, openingElem, openingGUID, solid, scaledWidth, openingData.IsRecess, extrusionCreationData, 
                            setter, localWrapper);
                    }
                }

                foreach (IFCExtrusionData extrusionData in extrusionDataList)
                {
                    if (extrusionData.ScaledExtrusionLength < MathUtil.Eps())
                        extrusionData.ScaledExtrusionLength = scaledWidth;

                    string openingGUID = null;
                    if (canUseElementGUID)
                    {
                        openingGUID = GUIDUtil.CreateGUID(element);
                        canUseElementGUID = false;
                    }
                    else
                        openingGUID = GUIDUtil.CreateGUID();
                    CreateOpening(exporterIFC, parentHandle, localPlacement, element, openingElem, openingGUID, extrusionData, plane, openingData.IsRecess, 
                        setter, localWrapper);
                }
            }
        }
示例#4
0
        /// <summary>
        /// Creates openings associated with an extrusion, if there are any.
        /// </summary>
        /// <param name="elementHandle">The element handle to create openings.</param>
        /// <param name="element">The element to create openings.</param>
        /// <param name="extraParams">The extrusion creation data.</param>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="originalPlacement">The original placement handle.</param>
        /// <param name="setter">The PlacementSetter.</param>
        /// <param name="wrapper">The ProductWrapper.</param>
        public static void CreateOpeningsIfNecessary(IFCAnyHandle elementHandle, Element element, IFCExtrusionCreationData extraParams,
           Transform offsetTransform, ExporterIFC exporterIFC, IFCAnyHandle originalPlacement,
           PlacementSetter setter, ProductWrapper wrapper)
        {
            if (IFCAnyHandleUtil.IsNullOrHasNoValue(elementHandle))
                return;

            ElementId categoryId = CategoryUtil.GetSafeCategoryId(element);

            IList<IFCExtrusionData> info = extraParams.GetOpenings();
            CreateOpeningsIfNecessaryBase(elementHandle, element, info, extraParams, offsetTransform, exporterIFC, originalPlacement, setter, wrapper);
            extraParams.ClearOpenings();
        }
示例#5
0
        /// <summary>
        /// Creates openings associated with an extrusion, if there are any.
        /// </summary>
        /// <param name="elementHandle">The element handle to create openings.</param>
        /// <param name="element">The element to create openings.</param>
        /// <param name="info">The extrusion data.</param>
        /// <param name="offsetTransform">The offset transform from ExportBody, or the identity transform.</param>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="originalPlacement">The original placement handle.</param>
        /// <param name="setter">The PlacementSetter.</param>
        /// <param name="wrapper">The ProductWrapper.</param>
        public static void CreateOpeningsIfNecessary(IFCAnyHandle elementHandle, Element element, IList<IFCExtrusionData> info, Transform offsetTransform,
           ExporterIFC exporterIFC, IFCAnyHandle originalPlacement,
           PlacementSetter setter, ProductWrapper wrapper)
        {
            if (IFCAnyHandleUtil.IsNullOrHasNoValue(elementHandle))
                return;

            using (IFCExtrusionCreationData extraParams = new IFCExtrusionCreationData())
            {
                CreateOpeningsIfNecessaryBase(elementHandle, element, info, extraParams, offsetTransform, exporterIFC, originalPlacement, setter, wrapper);
            }
        }
示例#6
0
        /// <summary>
        /// Exports curtain object as one Brep.
        /// </summary>
        /// <param name="allSubElements">
        /// Collection of elements contained in the host curtain element.
        /// </param>
        /// <param name="wallElement">
        /// The curtain wall element.
        /// </param>
        /// <param name="exporterIFC">
        /// The ExporterIFC object.
        /// </param>
        /// <param name="setter">
        /// The PlacementSetter object.
        /// </param>
        /// <param name="localPlacement">
        /// The local placement handle.
        /// </param>
        /// <returns>
        /// The handle.
        /// </returns>
        public static IFCAnyHandle ExportCurtainObjectCommonAsOneBRep(ICollection<ElementId> allSubElements, Element wallElement,
           ExporterIFC exporterIFC, PlacementSetter setter, IFCAnyHandle localPlacement)
        {
            IFCAnyHandle prodDefRep = null;
            Document document = wallElement.Document;
            double eps = UnitUtil.ScaleLength(document.Application.VertexTolerance);

            IFCFile file = exporterIFC.GetFile();
            IFCAnyHandle contextOfItems = exporterIFC.Get3DContextHandle("Body");

            IFCGeometryInfo info = IFCGeometryInfo.CreateFaceGeometryInfo(eps);

            ISet<IFCAnyHandle> bodyItems = new HashSet<IFCAnyHandle>();

            // Want to make sure we don't accidentally add a mullion or curtain line more than once.
            HashSet<ElementId> alreadyVisited = new HashSet<ElementId>();

            Options geomOptions = GeometryUtil.GetIFCExportGeometryOptions();
            foreach (ElementId subElemId in allSubElements)
            {
                Element subElem = wallElement.Document.GetElement(subElemId);
                GeometryElement geomElem = subElem.get_Geometry(geomOptions);
                if (geomElem == null)
                    continue;

                if (alreadyVisited.Contains(subElem.Id))
                    continue;
                alreadyVisited.Add(subElem.Id);

                ExporterIFCUtils.CollectGeometryInfo(exporterIFC, info, geomElem, XYZ.Zero, false);
                HashSet<IFCAnyHandle> faces = new HashSet<IFCAnyHandle>(info.GetSurfaces());
                IFCAnyHandle outer = IFCInstanceExporter.CreateClosedShell(file, faces);

                if (!IFCAnyHandleUtil.IsNullOrHasNoValue(outer))
                    bodyItems.Add(RepresentationUtil.CreateFacetedBRep(exporterIFC, document, outer, ElementId.InvalidElementId));
            }

            if (bodyItems.Count == 0)
                return prodDefRep;

            ElementId catId = CategoryUtil.GetSafeCategoryId(wallElement);
            IFCAnyHandle shapeRep = RepresentationUtil.CreateBRepRep(exporterIFC, wallElement, catId, contextOfItems, bodyItems);
            if (IFCAnyHandleUtil.IsNullOrHasNoValue(shapeRep))
                return prodDefRep;

            IList<IFCAnyHandle> shapeReps = new List<IFCAnyHandle>();
            shapeReps.Add(shapeRep);

            IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, wallElement.get_Geometry(geomOptions), Transform.Identity);
            if (boundingBoxRep != null)
                shapeReps.Add(boundingBoxRep);

            prodDefRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps);
            return prodDefRep;
        }
        /// <summary>
        /// Creates IFC room/space/area item, not include boundaries. 
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="spatialElement">The spatial element.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        /// <param name="setter">The PlacementSetter.</param>
        /// <returns>True if created successfully, false otherwise.</returns>
        static bool CreateIFCSpace(ExporterIFC exporterIFC, SpatialElement spatialElement, ProductWrapper productWrapper, 
            PlacementSetter setter, out SpatialElementGeometryResults results)
        {
            results = null;

            IList<CurveLoop> curveLoops = null;
            try
            {
                // Avoid throwing for a spatial element with no location.
                if (spatialElement.Location == null)
                    return false;

                SpatialElementBoundaryOptions options = GetSpatialElementBoundaryOptions(spatialElement);
                curveLoops = ExporterIFCUtils.GetRoomBoundaryAsCurveLoopArray(spatialElement, options, true);
            }
            catch (Autodesk.Revit.Exceptions.InvalidOperationException)
            {
                //Some spatial elements are not placed that have no boundary loops. Don't export them.
                return false;
            }

            Autodesk.Revit.DB.Document document = spatialElement.Document;
            ElementId levelId = spatialElement.LevelId;

            ElementId catId = spatialElement.Category != null ? spatialElement.Category.Id : ElementId.InvalidElementId;

            double dArea = 0.0;
            if (ParameterUtil.GetDoubleValueFromElement(spatialElement, BuiltInParameter.ROOM_AREA, out dArea) != null)
                dArea = UnitUtil.ScaleArea(dArea);

            IFCLevelInfo levelInfo = exporterIFC.GetLevelInfo(levelId);

            string strSpaceNumber = null;
            string strSpaceName = null;
            string strSpaceDesc = null;

            if (ParameterUtil.GetStringValueFromElement(spatialElement, BuiltInParameter.ROOM_NUMBER, out strSpaceNumber) == null)
                strSpaceNumber = null;

            if (ParameterUtil.GetStringValueFromElement(spatialElement, BuiltInParameter.ROOM_NAME, out strSpaceName) == null)
                strSpaceName = null;

            if (ParameterUtil.GetStringValueFromElement(spatialElement, BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS, out strSpaceDesc) == null)
                strSpaceDesc = null;

            string name = strSpaceNumber;
            string longName = strSpaceName;
            string desc = strSpaceDesc;

            IFCFile file = exporterIFC.GetFile();

            IFCAnyHandle localPlacement = setter.LocalPlacement;
            ElementType elemType = document.GetElement(spatialElement.GetTypeId()) as ElementType;
            IFCInternalOrExternal internalOrExternal = CategoryUtil.IsElementExternal(spatialElement) ? IFCInternalOrExternal.External : IFCInternalOrExternal.Internal;

            double scaledRoomHeight = GetScaledHeight(spatialElement, levelId, levelInfo);
            if (scaledRoomHeight <= 0.0)
                return false;

            double bottomOffset;
            ParameterUtil.GetDoubleValueFromElement(spatialElement, BuiltInParameter.ROOM_LOWER_OFFSET, out bottomOffset);

         double elevation = (levelInfo != null) ? levelInfo.Elevation : 0.0;
            XYZ zDir = new XYZ(0, 0, 1);
         XYZ orig = new XYZ(0, 0, elevation + bottomOffset);

            Plane plane = new Plane(zDir, orig); // room calculated as level offset.

            GeometryElement geomElem = null;
            bool isArea = (spatialElement is Area);
            Area spatialElementAsArea = isArea ? (spatialElement as Area) : null;

            if (spatialElement is Autodesk.Revit.DB.Architecture.Room)
            {
                Autodesk.Revit.DB.Architecture.Room room = spatialElement as Autodesk.Revit.DB.Architecture.Room;
                geomElem = room.ClosedShell;
            }
            else if (spatialElement is Autodesk.Revit.DB.Mechanical.Space)
            {
                Autodesk.Revit.DB.Mechanical.Space space = spatialElement as Autodesk.Revit.DB.Mechanical.Space;
                geomElem = space.ClosedShell;
            }
            else if (isArea)
            {
                Options geomOptions = GeometryUtil.GetIFCExportGeometryOptions();
                geomElem = spatialElementAsArea.get_Geometry(geomOptions);
            }

            IFCAnyHandle spaceHnd = null;
            string spatialElementName = null;
            using (IFCExtrusionCreationData extraParams = new IFCExtrusionCreationData())
            {
                extraParams.SetLocalPlacement(localPlacement);
                extraParams.PossibleExtrusionAxes = IFCExtrusionAxes.TryZ;

                using (IFCTransaction transaction2 = new IFCTransaction(file))
                {
                    IFCAnyHandle repHnd = null;
                    if (!ExporterCacheManager.ExportOptionsCache.Use2DRoomBoundaryForRoomVolumeCreation && geomElem != null)
                    {
                        BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true);
                        bodyExporterOptions.TessellationLevel = BodyExporter.GetTessellationLevel();
                        repHnd = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, spatialElement,
                            catId, geomElem, bodyExporterOptions, null, extraParams, false);
                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(repHnd))
                            extraParams.ClearOpenings();
                    }
                    else
                    {
                        IFCAnyHandle shapeRep = ExtrusionExporter.CreateExtrudedSolidFromCurveLoop(exporterIFC, null, curveLoops, plane, zDir, scaledRoomHeight);
                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(shapeRep))
                            return false;
                        IFCAnyHandle styledItemHnd = BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, document,
                            shapeRep, ElementId.InvalidElementId);

                        HashSet<IFCAnyHandle> bodyItems = new HashSet<IFCAnyHandle>();
                        bodyItems.Add(shapeRep);
                        shapeRep = RepresentationUtil.CreateSweptSolidRep(exporterIFC, spatialElement, catId, exporterIFC.Get3DContextHandle("Body"), bodyItems, null);
                        IList<IFCAnyHandle> shapeReps = new List<IFCAnyHandle>();
                        shapeReps.Add(shapeRep);

                        IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, geomElem, Transform.Identity);
                        if (boundingBoxRep != null)
                            shapeReps.Add(boundingBoxRep);

                        repHnd = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps);
                    }

                    extraParams.ScaledHeight = scaledRoomHeight;
                    extraParams.ScaledArea = dArea;

                    spatialElementName = NamingUtil.GetNameOverride(spatialElement, name);
                    string spatialElementDescription = NamingUtil.GetDescriptionOverride(spatialElement, desc);
                    string spatialElementObjectType = NamingUtil.GetObjectTypeOverride(spatialElement, null);
                    string spatialElementLongName = NamingUtil.GetLongNameOverride(spatialElement, longName);
                    
                    double? spaceElevationWithFlooring = null;
                    double elevationWithFlooring = 0.0;
                    if (ParameterUtil.GetDoubleValueFromElement(spatialElement, null, "IfcElevationWithFlooring", out elevationWithFlooring) != null)
                        spaceElevationWithFlooring = UnitUtil.ScaleLength(elevationWithFlooring);
                    spaceHnd = IFCInstanceExporter.CreateSpace(file, GUIDUtil.CreateGUID(spatialElement),
                                                  ExporterCacheManager.OwnerHistoryHandle,
                                                  spatialElementName, spatialElementDescription, spatialElementObjectType,
                                                  extraParams.GetLocalPlacement(), repHnd, spatialElementLongName, Toolkit.IFCElementComposition.Element,
                                                  internalOrExternal, spaceElevationWithFlooring);

                    transaction2.Commit();
                }

                if (spaceHnd != null)
                {
                    productWrapper.AddSpace(spatialElement, spaceHnd, levelInfo, extraParams, true);
                    if (isArea)
                    {
                        Element areaScheme = spatialElementAsArea.AreaScheme;
                        if (areaScheme != null)
                        {
                            ElementId areaSchemeId = areaScheme.Id;
                            HashSet<IFCAnyHandle> areas = null;
                            if (!ExporterCacheManager.AreaSchemeCache.TryGetValue(areaSchemeId, out areas))
                            {
                                areas = new HashSet<IFCAnyHandle>();
                                ExporterCacheManager.AreaSchemeCache[areaSchemeId] = areas;
                            }
                            areas.Add(spaceHnd);
                        }
                    }
                }
            }

            // Save room handle for later use/relationships
            ExporterCacheManager.SpaceInfoCache.SetSpaceHandle(spatialElement, spaceHnd);

            // Find Ceiling as a Space boundary and keep the relationship in a cache for use later
            bool ret = GetCeilingSpaceBoundary(spatialElement, out results);

         if (!MathUtil.IsAlmostZero(dArea) && !(ExporterCacheManager.ExportOptionsCache.ExportAsCOBIE) &&
                !ExporterCacheManager.ExportOptionsCache.ExportAs2x3CoordinationView2 && !ExporterCacheManager.ExportOptionsCache.ExportBaseQuantities)
            {
                bool isDesignGrossArea = (string.Compare(spatialElementName, "GSA Design Gross Area") > 0);
                PropertyUtil.CreatePreCOBIEGSAQuantities(exporterIFC, spaceHnd, "GSA Space Areas", (isDesignGrossArea ? "GSA Design Gross Area" : "GSA BIM Area"), dArea);
            }

            // Export Classifications for SpatialElement for GSA/COBIE.
         if (ExporterCacheManager.ExportOptionsCache.ExportAsCOBIE)
            {
                ProjectInfo projectInfo = document.ProjectInformation;
                if (projectInfo != null)
                    CreateCOBIESpaceClassifications(exporterIFC, file, spaceHnd, projectInfo, spatialElement);
            }

            return true;
        }
        /// <summary>
        /// Exports mullion.
        /// </summary>
        /// <param name="exporterIFC">
        /// The ExporterIFC object.
        /// </param>
        /// <param name="mullion">
        /// The mullion object.
        /// </param>
        /// <param name="geometryElement">
        /// The geometry element.
        /// </param>
        /// <param name="localPlacement">
        /// The local placement handle.
        /// </param>
        /// <param name="setter">
        /// The PlacementSetter.
        /// </param>
        /// <param name="productWrapper">
        /// The ProductWrapper.
        /// </param>
        public static void Export(ExporterIFC exporterIFC, Mullion mullion, GeometryElement geometryElement,
           IFCAnyHandle localPlacement, PlacementSetter setter, ProductWrapper productWrapper)
        {
            IFCFile file = exporterIFC.GetFile();

            using (PlacementSetter mullionSetter = PlacementSetter.Create(exporterIFC, mullion))
            {
                using (IFCExtrusionCreationData extraParams = new IFCExtrusionCreationData())
                {
                    IFCAnyHandle mullionPlacement = mullionSetter.LocalPlacement;
                    
                    Transform relTrf = ExporterIFCUtils.GetRelativeLocalPlacementOffsetTransform(localPlacement, mullionPlacement);
                    Transform inverseTrf = relTrf.Inverse;

                    IFCAnyHandle mullionLocalPlacement = ExporterUtil.CreateLocalPlacement(file, localPlacement,
                        inverseTrf.Origin, inverseTrf.BasisZ, inverseTrf.BasisX);

                    extraParams.SetLocalPlacement(mullionLocalPlacement);

                    Transform extrusionLCS = null;
                    // Add a custom direction for trying to create an extrusion based on the base curve of the mullion, if it is a line and not an arc.
                    Curve baseCurve = mullion.LocationCurve;
                    if ((baseCurve != null) && (baseCurve is Line))
                    {
                        // We won't use curveBounds and origin yet; just need the axis for now.
                        IFCRange curveBounds;
                        XYZ origin, mullionDirection;
                        GeometryUtil.GetAxisAndRangeFromCurve(baseCurve, out curveBounds, out mullionDirection, out origin);

                        // approx 1.0/sqrt(2.0)
                        XYZ planeY = (Math.Abs(mullionDirection.Z) < 0.707) ? XYZ.BasisZ.CrossProduct(mullionDirection) : XYZ.BasisX.CrossProduct(mullionDirection);
                        planeY.Normalize();

                        XYZ projDir = mullionDirection.CrossProduct(planeY);

                        extrusionLCS = Transform.Identity;
                        extrusionLCS.BasisX = mullionDirection; extrusionLCS.BasisY = planeY; extrusionLCS.BasisZ = projDir; extrusionLCS.Origin = origin;
                    }

                    ElementId catId = CategoryUtil.GetSafeCategoryId(mullion);

                    BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true);
                    bodyExporterOptions.ExtrusionLocalCoordinateSystem = extrusionLCS;

                    IFCAnyHandle repHnd = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, mullion, catId,
                        geometryElement, bodyExporterOptions, null, extraParams, true);
                    if (IFCAnyHandleUtil.IsNullOrHasNoValue(repHnd))
                    {
                        extraParams.ClearOpenings();
                        return;
                    }

                    string elemGUID = GUIDUtil.CreateGUID(mullion);
                    IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle();
                    string elemObjectType = NamingUtil.CreateIFCObjectName(exporterIFC, mullion);
                    string name = NamingUtil.GetNameOverride(mullion, elemObjectType);
                    string description = NamingUtil.GetDescriptionOverride(mullion, null);
                    string objectType = NamingUtil.GetObjectTypeOverride(mullion, elemObjectType);
                    string elemTag = NamingUtil.GetTagOverride(mullion, NamingUtil.CreateIFCElementId(mullion));

                    IFCAnyHandle mullionHnd = IFCInstanceExporter.CreateMember(file, elemGUID, ownerHistory, name, description, objectType,
                       mullionLocalPlacement, repHnd, elemTag, "MULLION");
                    ExporterCacheManager.HandleToElementCache.Register(mullionHnd, mullion.Id);

                    productWrapper.AddElement(mullion, mullionHnd, mullionSetter, extraParams, false);

                    ElementId matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geometryElement, exporterIFC, mullion);
                    CategoryUtil.CreateMaterialAssociation(exporterIFC, mullionHnd, matId);
                }
            }
        }
示例#9
0
        /// <summary>
        /// Creates an opening from extrusion data.
        /// </summary>
        /// <param name="exporterIFC">The exporter.</param>
        /// <param name="hostObjHnd">The host handle.</param>
        /// <param name="hostPlacement">The host placement.</param>
        /// <param name="hostElement">The host element.</param>
        /// <param name="insertElement">The opening element.</param>
        /// <param name="openingGUID">The opening GUID.</param>
        /// <param name="extrusionData">The extrusion data.</param>
        /// <param name="plane">The plane.</param>
        /// <param name="isRecess">True if it is a recess.</param>
        /// <returns>The opening handle.</returns>
        static public IFCAnyHandle CreateOpening(ExporterIFC exporterIFC, IFCAnyHandle hostObjHnd, IFCAnyHandle hostPlacement, Element hostElement, 
            Element insertElement, string openingGUID, IFCExtrusionData extrusionData, Plane plane, bool isRecess, 
            PlacementSetter setter, ProductWrapper localWrapper)
        {
            IFCFile file = exporterIFC.GetFile();

            IList<CurveLoop> curveLoops = extrusionData.GetLoops();

            if (curveLoops.Count == 0)
                return null;

            if (plane == null)
            {
                // assumption: first curve loop defines the plane.
                if (!curveLoops[0].HasPlane())
                    return null;
                plane = curveLoops[0].GetPlane();
            }

            ElementId catId = CategoryUtil.GetSafeCategoryId(insertElement);

            IFCAnyHandle openingProdRepHnd = RepresentationUtil.CreateExtrudedProductDefShape(exporterIFC, insertElement, catId,
                curveLoops, plane, extrusionData.ExtrusionDirection, extrusionData.ScaledExtrusionLength);

            string openingObjectType = isRecess ? "Recess" : "Opening";
            IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle();
            string openingName = NamingUtil.GetNameOverride(insertElement, null);
            if (string.IsNullOrEmpty(openingName))
                openingName = NamingUtil.GetNameOverride(hostElement, NamingUtil.CreateIFCObjectName(exporterIFC, hostElement));
            IFCAnyHandle openingHnd = IFCInstanceExporter.CreateOpeningElement(file, openingGUID, ownerHistory, openingName, null,
                openingObjectType, ExporterUtil.CreateLocalPlacement(file, hostPlacement, null), openingProdRepHnd, null);
            IFCExtrusionCreationData ecData = null;
            if (ExporterCacheManager.ExportOptionsCache.ExportBaseQuantities)
            {
                double height, width;
                ecData = new IFCExtrusionCreationData();
                if (GeometryUtil.ComputeHeightWidthOfCurveLoop(curveLoops[0], plane, out height, out width))
                {
                    ecData.ScaledHeight = UnitUtil.ScaleLength(height);
                    ecData.ScaledWidth = UnitUtil.ScaleLength(width);
                }
                else
                {
                    double area = ExporterIFCUtils.ComputeAreaOfCurveLoops(curveLoops);
                    ecData.ScaledArea = UnitUtil.ScaleArea(area);
                }
                PropertyUtil.CreateOpeningQuantities(exporterIFC, openingHnd, ecData);
            }

            if (localWrapper != null)
            {
                Element elementForProperties = null;
                if (GUIDUtil.IsGUIDFor(insertElement, openingGUID))
                    elementForProperties = insertElement;

                localWrapper.AddElement(elementForProperties, openingHnd, setter, ecData, true);
            }

            string voidGuid = GUIDUtil.CreateGUID();
            IFCInstanceExporter.CreateRelVoidsElement(file, voidGuid, ownerHistory, null, null, hostObjHnd, openingHnd);
            return openingHnd;
        }
        /// <summary>
        /// Exports curtain object as container.
        /// </summary>
        /// <param name="allSubElements">
        /// Collection of elements contained in the host curtain element.
        /// </param>
        /// <param name="wallElement">
        /// The curtain wall element.
        /// </param>
        /// <param name="exporterIFC">
        /// The ExporterIFC object.
        /// </param>
        /// <param name="productWrapper">
        /// The ProductWrapper.
        /// </param>
        public static void ExportCurtainObjectCommonAsContainer(ICollection<ElementId> allSubElements, Element wallElement,
           ExporterIFC exporterIFC, ProductWrapper origWrapper, PlacementSetter currSetter)
        {
            if (wallElement == null)
                return;

            string overrideCADLayer = null;
            ParameterUtil.GetStringValueFromElementOrSymbol(wallElement, "IFCCadLayer", out overrideCADLayer);

            using (ExporterStateManager.CADLayerOverrideSetter layerSetter = new ExporterStateManager.CADLayerOverrideSetter(overrideCADLayer))
            {
                HashSet<ElementId> alreadyVisited = new HashSet<ElementId>();  // just in case.
                Options geomOptions = GeometryUtil.GetIFCExportGeometryOptions();
                {
                    foreach (ElementId subElemId in allSubElements)
                    {
                        using (ProductWrapper productWrapper = ProductWrapper.Create(origWrapper))
                        {
                            Element subElem = wallElement.Document.GetElement(subElemId);
                            if (subElem == null)
                                continue;

                            if (alreadyVisited.Contains(subElem.Id))
                                continue;
                            alreadyVisited.Add(subElem.Id);

                            // Respect element visibility settings.
                            if (!ElementFilteringUtil.CanExportElement(exporterIFC, subElem, false) || !ElementFilteringUtil.IsElementVisible(subElem))
                                continue;

                            GeometryElement geomElem = subElem.get_Geometry(geomOptions);
                            if (geomElem == null)
                                continue;

                            try
                            {
                                if (subElem is FamilyInstance)
                                {
                                    if (subElem is Mullion)
                                    {
                                        if (ExporterCacheManager.ExportOptionsCache.ExportAs2x2)
                                            ProxyElementExporter.Export(exporterIFC, subElem, geomElem, productWrapper);
                                        else
                                        {
                                            IFCAnyHandle currLocalPlacement = currSetter.LocalPlacement;
                                            MullionExporter.Export(exporterIFC, subElem as Mullion, geomElem, currLocalPlacement, currSetter,
                                                productWrapper);
                                        }
                                    }
                                    else
                                    {
                                        FamilyInstance subFamInst = subElem as FamilyInstance;

                                        string ifcEnumType;
                                        IFCExportType exportType = ExporterUtil.GetExportType(exporterIFC, subElem, out ifcEnumType);
                                        if (exportType == IFCExportType.IfcCurtainWall)
                                        {
                                            // By default, panels and mullions are set to the same category as their parent.  In this case,
                                            // ask to get the exportType from the category id, since we don't want to inherit the parent class.
                                            ElementId catId = CategoryUtil.GetSafeCategoryId(subElem);
                                            exportType = ElementFilteringUtil.GetExportTypeFromCategoryId(catId, out ifcEnumType);
                                        }


                                        if (ExporterCacheManager.ExportOptionsCache.ExportAs2x2)
                                        {
                                            if ((exportType == IFCExportType.DontExport) || (exportType == IFCExportType.IfcPlateType) ||
                                               (exportType == IFCExportType.IfcMemberType))
                                                exportType = IFCExportType.IfcBuildingElementProxyType;
                                        }
                                        else
                                        {
                                            if (exportType == IFCExportType.DontExport)
                                            {
                                                ifcEnumType = "CURTAIN_PANEL";
                                                exportType = IFCExportType.IfcPlateType;
                                            }
                                        }

                                        IFCAnyHandle currLocalPlacement = currSetter.LocalPlacement;
                                        using (IFCExtrusionCreationData extraParams = new IFCExtrusionCreationData())
                                        {
                                            FamilyInstanceExporter.ExportFamilyInstanceAsMappedItem(exporterIFC, subFamInst, exportType, ifcEnumType, productWrapper,
                                                ElementId.InvalidElementId, null, currLocalPlacement);
                                        }
                                    }
                                }
                                else if (subElem is CurtainGridLine)
                                {
                                    ProxyElementExporter.Export(exporterIFC, subElem, geomElem, productWrapper);
                                }
                                else if (subElem is Wall)
                                {
                                    WallExporter.ExportWall(exporterIFC, subElem, null, geomElem, productWrapper);
                                }
                            }
                            catch (Exception ex)
                            {
                                if (ExporterUtil.IsFatalException(wallElement.Document, ex))
                                    throw ex;
                                continue;
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Exports curtain object as one Brep.
        /// </summary>
        /// <param name="allSubElements">
        /// Collection of elements contained in the host curtain element.
        /// </param>
        /// <param name="wallElement">
        /// The curtain wall element.
        /// </param>
        /// <param name="exporterIFC">
        /// The ExporterIFC object.
        /// </param>
        /// <param name="setter">
        /// The PlacementSetter object.
        /// </param>
        /// <param name="localPlacement">
        /// The local placement handle.
        /// </param>
        /// <returns>
        /// The handle.
        /// </returns>
        public static IFCAnyHandle ExportCurtainObjectCommonAsOneBRep(ICollection<ElementId> allSubElements, Element wallElement,
           ExporterIFC exporterIFC, PlacementSetter setter, IFCAnyHandle localPlacement)
        {
            IFCAnyHandle prodDefRep = null;
            Document document = wallElement.Document;
            double eps = UnitUtil.ScaleLength(document.Application.VertexTolerance);

            IFCFile file = exporterIFC.GetFile();
            IFCAnyHandle contextOfItems = exporterIFC.Get3DContextHandle("Body");

            IFCGeometryInfo info = IFCGeometryInfo.CreateFaceGeometryInfo(eps);

            ISet<IFCAnyHandle> bodyItems = new HashSet<IFCAnyHandle>();

            // Want to make sure we don't accidentally add a mullion or curtain line more than once.
            HashSet<ElementId> alreadyVisited = new HashSet<ElementId>();
            bool useFallbackBREP = true;
            Options geomOptions = GeometryUtil.GetIFCExportGeometryOptions();

            foreach (ElementId subElemId in allSubElements)
            {
                Element subElem = wallElement.Document.GetElement(subElemId);
                GeometryElement geomElem = subElem.get_Geometry(geomOptions);
                if (geomElem == null)
                    continue;

                if (alreadyVisited.Contains(subElem.Id))
                    continue;
                alreadyVisited.Add(subElem.Id);


                // Export tessellated geometry when IFC4 Reference View is selected
                if (ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView)
                {
                    BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(false);
                    IFCAnyHandle triFaceSet = BodyExporter.ExportBodyAsTriangulatedFaceSet(exporterIFC, subElem, bodyExporterOptions, geomElem);
                    if (!IFCAnyHandleUtil.IsNullOrHasNoValue(triFaceSet))
                    {
                        bodyItems.Add(triFaceSet);
                        useFallbackBREP = false;    // no need to do Brep since it is successful
                    }
                }
                // Export AdvancedFace before use fallback BREP
                else if (ExporterCacheManager.ExportOptionsCache.ExportAs4DesignTransferView)
                {
                    BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(false);
                    IFCAnyHandle advancedBRep = BodyExporter.ExportBodyAsAdvancedBrep(exporterIFC, subElem, bodyExporterOptions, geomElem);
                    if (!IFCAnyHandleUtil.IsNullOrHasNoValue(advancedBRep))
                    {
                        bodyItems.Add(advancedBRep);
                        useFallbackBREP = false;    // no need to do Brep since it is successful
                    }
                }

                if (useFallbackBREP)
                {
                    ExporterIFCUtils.CollectGeometryInfo(exporterIFC, info, geomElem, XYZ.Zero, false);
                    HashSet<IFCAnyHandle> faces = new HashSet<IFCAnyHandle>(info.GetSurfaces());
                    IFCAnyHandle outer = IFCInstanceExporter.CreateClosedShell(file, faces);

                    if (!IFCAnyHandleUtil.IsNullOrHasNoValue(outer))
                        bodyItems.Add(RepresentationUtil.CreateFacetedBRep(exporterIFC, document, outer, ElementId.InvalidElementId));
                }
            }

            if (bodyItems.Count == 0)
                return prodDefRep;

            ElementId catId = CategoryUtil.GetSafeCategoryId(wallElement);
            IFCAnyHandle shapeRep;

            // Use tessellated geometry in Reference View
            if (ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView && !useFallbackBREP)
                shapeRep = RepresentationUtil.CreateTessellatedRep(exporterIFC, wallElement, catId, contextOfItems, bodyItems, null);
            else if (ExporterCacheManager.ExportOptionsCache.ExportAs4DesignTransferView && !useFallbackBREP)
                shapeRep = RepresentationUtil.CreateAdvancedBRepRep(exporterIFC, wallElement, catId, contextOfItems, bodyItems, null);
            else
                shapeRep = RepresentationUtil.CreateBRepRep(exporterIFC, wallElement, catId, contextOfItems, bodyItems);

            if (IFCAnyHandleUtil.IsNullOrHasNoValue(shapeRep))
                return prodDefRep;

            IList<IFCAnyHandle> shapeReps = new List<IFCAnyHandle>();
            shapeReps.Add(shapeRep);

            IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, wallElement.get_Geometry(geomOptions), Transform.Identity);
            if (boundingBoxRep != null)
                shapeReps.Add(boundingBoxRep);

            prodDefRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps);
            return prodDefRep;
        }
      private static void ExportAsMappedItem(ExporterIFC exporterIFC, Element element, IFCFile file, IFCExportType exportType, string ifcEnumType, IFCExtrusionCreationData extraParams,
          PlacementSetter setter, IFCAnyHandle localPlacementToUse, IFCAnyHandle productRepresentation, ProductWrapper productWrapper)
      {
         IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle;
         ElementId typeId = element.GetTypeId();
         ElementType type = element.Document.GetElement(typeId) as ElementType;
         IFCAnyHandle styleHandle = null;

         if (type != null)
         {
            FamilyTypeInfo currentTypeInfo = ExporterCacheManager.TypeObjectsCache.Find(typeId, false, exportType);

            bool found = currentTypeInfo.IsValid();
            if (!found)
            {
               string typeGUID = GUIDUtil.CreateGUID(type);
               string typeName = NamingUtil.GetIFCName(type);
               string typeObjectType = NamingUtil.CreateIFCObjectName(exporterIFC, type);
               string applicableOccurance = NamingUtil.GetObjectTypeOverride(type, typeObjectType);
               string typeDescription = NamingUtil.GetDescriptionOverride(type, null);
               string typeElemId = NamingUtil.CreateIFCElementId(type);

               HashSet<IFCAnyHandle> propertySetsOpt = new HashSet<IFCAnyHandle>();
               IList<IFCAnyHandle> repMapListOpt = new List<IFCAnyHandle>();

               styleHandle = FamilyExporterUtil.ExportGenericType(exporterIFC, exportType, ifcEnumType, typeGUID, typeName,
                   typeDescription, applicableOccurance, propertySetsOpt, repMapListOpt, typeElemId, typeName, element, type);
               if (!IFCAnyHandleUtil.IsNullOrHasNoValue(styleHandle))
               {
                  currentTypeInfo.Style = styleHandle;
                  ExporterCacheManager.TypeObjectsCache.Register(typeId, false, exportType, currentTypeInfo);
               }
            }
            else
            {
               styleHandle = currentTypeInfo.Style;
            }
         }

         string instanceGUID = GUIDUtil.CreateGUID(element);
         string instanceName = NamingUtil.GetIFCName(element);
         string objectType = NamingUtil.CreateIFCObjectName(exporterIFC, element);
         string instanceObjectType = NamingUtil.GetObjectTypeOverride(element, objectType);
         string instanceDescription = NamingUtil.GetDescriptionOverride(element, null);
         string instanceElemId = NamingUtil.CreateIFCElementId(element);
         string instanceTag = NamingUtil.GetTagOverride(element, NamingUtil.CreateIFCElementId(element));

         bool roomRelated = !FamilyExporterUtil.IsDistributionFlowElementSubType(exportType);

         ElementId roomId = ElementId.InvalidElementId;
         if (roomRelated)
         {
            roomId = setter.UpdateRoomRelativeCoordinates(element, out localPlacementToUse);
         }

         IFCAnyHandle instanceHandle = null;

         // For MEP objects
         string exportEntityStr = exportType.ToString();
         Common.Enums.IFCEntityType exportEntity;

         if (String.Compare(exportEntityStr.Substring(exportEntityStr.Length - 4), "Type", true) == 0)
            exportEntityStr = exportEntityStr.Substring(0, (exportEntityStr.Length - 4));
         if (Enum.TryParse(exportEntityStr, out exportEntity))
         {
            // For MEP object creation
            instanceHandle = IFCInstanceExporter.CreateGenericIFCEntity(exportEntity, file, instanceGUID, ownerHistory,
               instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceTag);
         }

         if (IFCAnyHandleUtil.IsNullOrHasNoValue(instanceHandle))
            return;

         if (roomId != ElementId.InvalidElementId)
         {
            //exporterIFC.RelateSpatialElement(roomId, instanceHandle);
            ExporterCacheManager.SpaceInfoCache.RelateToSpace(roomId, instanceHandle);
            productWrapper.AddElement(element, instanceHandle, setter, extraParams, false);
         }
         else
         {
            productWrapper.AddElement(element, instanceHandle, setter, extraParams, true);
         }

         OpeningUtil.CreateOpeningsIfNecessary(instanceHandle, element, extraParams, null, exporterIFC, localPlacementToUse, setter, productWrapper);

         if (!IFCAnyHandleUtil.IsNullOrHasNoValue(styleHandle))
            ExporterCacheManager.TypeRelationsCache.Add(styleHandle, instanceHandle);

         PropertyUtil.CreateInternalRevitPropertySets(exporterIFC, element, productWrapper.GetAllObjects());

         ExporterCacheManager.MEPCache.Register(element, instanceHandle);

         // add to system export cache
         // SystemExporter.ExportSystem(exporterIFC, element, instanceHandle);
      }
示例#13
0
        /// <summary>
        /// Exports the top stories of a multistory staircase.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="stair">The stairs element.</param>
        /// <param name="numFlights">The number of flights for a multistory staircase.</param>
        /// <param name="stairHnd">The stairs container handle.</param>
        /// <param name="components">The components handles.</param>
        /// <param name="ecData">The extrusion creation data.</param>
        /// <param name="componentECData">The extrusion creation data for the components.</param>
        /// <param name="placementSetter">The placement setter.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        public static void ExportMultistoryStair(ExporterIFC exporterIFC, Element stair, int numFlights,
            IFCAnyHandle stairHnd, IList<IFCAnyHandle> components, IList<IFCExtrusionCreationData> componentECData,
            PlacementSetter placementSetter, ProductWrapper productWrapper)
        {
            if (numFlights < 2)
                return;

            double heightNonScaled = GetStairsHeight(exporterIFC, stair);
            if (heightNonScaled < MathUtil.Eps())
                return;

            if (IFCAnyHandleUtil.IsNullOrHasNoValue(stairHnd))
                return;

            IFCAnyHandle localPlacement = IFCAnyHandleUtil.GetObjectPlacement(stairHnd);
            if (IFCAnyHandleUtil.IsNullOrHasNoValue(localPlacement))
                return;

            IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle();

            IFCFile file = exporterIFC.GetFile();

            IFCAnyHandle relPlacement = GeometryUtil.GetRelativePlacementFromLocalPlacement(localPlacement);
            IFCAnyHandle ptHnd = IFCAnyHandleUtil.GetLocation(relPlacement);
            IList<double> origCoords = IFCAnyHandleUtil.GetCoordinates(ptHnd);

            ICollection<ElementId> runIds = null;
            ICollection<ElementId> landingIds = null;
            ICollection<ElementId> supportIds = null;

            if (stair is Stairs)
            {
                Stairs stairAsStairs = stair as Stairs;
                runIds = stairAsStairs.GetStairsRuns();
                landingIds = stairAsStairs.GetStairsLandings();
                supportIds = stairAsStairs.GetStairsSupports();
            }

            IList<IFCAnyHandle> stairLocalPlacementHnds = new List<IFCAnyHandle>();
            IList<IFCLevelInfo> levelInfos = new List<IFCLevelInfo>();
            for (int ii = 0; ii < numFlights - 1; ii++)
            {
                IFCAnyHandle newLevelHnd = null;

                // We are going to avoid internal scaling routines, and instead scale in .NET.
                double newOffsetUnscaled = 0.0;
                IFCLevelInfo currLevelInfo =
                    placementSetter.GetOffsetLevelInfoAndHandle(heightNonScaled * (ii + 1), 1.0, stair.Document, out newLevelHnd, out newOffsetUnscaled);
                double newOffsetScaled = UnitUtil.ScaleLength(newOffsetUnscaled); 
                
                levelInfos.Add(currLevelInfo);
                if (levelInfos[ii] == null)
                    levelInfos[ii] = placementSetter.LevelInfo;

                XYZ orig;
                if (ptHnd.HasValue)
                {
                    orig = new XYZ(origCoords[0], origCoords[1], newOffsetScaled);
                }
                else
                {
                    orig = new XYZ(0.0, 0.0, newOffsetScaled);
                }
                stairLocalPlacementHnds.Add(ExporterUtil.CreateLocalPlacement(file, newLevelHnd, orig, null, null));
            }

            IList<List<IFCAnyHandle>> newComponents = new List<List<IFCAnyHandle>>();
            for (int ii = 0; ii < numFlights - 1; ii++)
                newComponents.Add(new List<IFCAnyHandle>());

            int compIdx = 0;
            IEnumerator<ElementId> runIter = null;
            if (runIds != null)
            {
                runIter = runIds.GetEnumerator();
                runIter.MoveNext();
            }
            IEnumerator<ElementId> landingIter = null;
            if (landingIds != null)
            {
                landingIter = landingIds.GetEnumerator();
                landingIter.MoveNext();
            }
            IEnumerator<ElementId> supportIter = null;
            if (supportIds != null)
            {
                supportIter = supportIds.GetEnumerator();
                supportIter.MoveNext();
            }

            foreach (IFCAnyHandle component in components)
            {
                string componentName = IFCAnyHandleUtil.GetStringAttribute(component, "Name");
                string componentDescription = IFCAnyHandleUtil.GetStringAttribute(component, "Description");
                string componentObjectType = IFCAnyHandleUtil.GetStringAttribute(component, "ObjectType");
                string componentElementTag = IFCAnyHandleUtil.GetStringAttribute(component, "Tag");
                IFCAnyHandle componentProdRep = IFCAnyHandleUtil.GetInstanceAttribute(component, "Representation");

                IList<string> localComponentNames = new List<string>();
                IList<IFCAnyHandle> componentPlacementHnds = new List<IFCAnyHandle>();

                IFCAnyHandle localLocalPlacement = IFCAnyHandleUtil.GetObjectPlacement(component);
                IFCAnyHandle localRelativePlacement =
                    (localLocalPlacement == null) ? null : IFCAnyHandleUtil.GetInstanceAttribute(localLocalPlacement, "RelativePlacement");

                bool isSubStair = component.IsSubTypeOf(IFCEntityType.IfcStair.ToString());
                for (int ii = 0; ii < numFlights - 1; ii++)
                {
                    localComponentNames.Add((componentName == null) ? (ii + 2).ToString() : (componentName + ":" + (ii + 2)));
                    if (isSubStair)
                        componentPlacementHnds.Add(ExporterUtil.CopyLocalPlacement(file, stairLocalPlacementHnds[ii]));
                    else
                        componentPlacementHnds.Add(IFCInstanceExporter.CreateLocalPlacement(file, stairLocalPlacementHnds[ii], localRelativePlacement));
                }

                IList<IFCAnyHandle> localComponentHnds = new List<IFCAnyHandle>();
                if (isSubStair)
                {
                    string componentType = IFCAnyHandleUtil.GetEnumerationAttribute(component, "ShapeType");
                    string localStairType = GetIFCStairType(componentType);

                    ElementId catId = CategoryUtil.GetSafeCategoryId(stair);

                    for (int ii = 0; ii < numFlights - 1; ii++)
                    {
                        IFCAnyHandle representationCopy =
                            ExporterUtil.CopyProductDefinitionShape(exporterIFC, stair, catId, componentProdRep);

                        localComponentHnds.Add(IFCInstanceExporter.CreateStair(file, GUIDUtil.CreateGUID(), ownerHistory,
                            localComponentNames[ii], componentDescription, componentObjectType, componentPlacementHnds[ii], representationCopy,
                            componentElementTag, localStairType));
                    }
                }
                else if (IFCAnyHandleUtil.IsSubTypeOf(component, IFCEntityType.IfcStairFlight))
                {
                    Element runElem = (runIter == null) ? stair : stair.Document.GetElement(runIter.Current);
                    Element runElemToUse = (runElem == null) ? stair : runElem;
                    ElementId catId = CategoryUtil.GetSafeCategoryId(runElemToUse);

                    int? numberOfRiser = IFCAnyHandleUtil.GetIntAttribute(component, "NumberOfRiser");
                    int? numberOfTreads = IFCAnyHandleUtil.GetIntAttribute(component, "NumberOfTreads");
                    double? riserHeight = IFCAnyHandleUtil.GetDoubleAttribute(component, "RiserHeight");
                    double? treadLength = IFCAnyHandleUtil.GetDoubleAttribute(component, "TreadLength");

                    for (int ii = 0; ii < numFlights - 1; ii++)
                    {
                        IFCAnyHandle representationCopy =
                            ExporterUtil.CopyProductDefinitionShape(exporterIFC, runElemToUse, catId, componentProdRep);

                        localComponentHnds.Add(IFCInstanceExporter.CreateStairFlight(file, GUIDUtil.CreateGUID(), ownerHistory,
                            localComponentNames[ii], componentDescription, componentObjectType, componentPlacementHnds[ii], representationCopy,
                            componentElementTag, numberOfRiser, numberOfTreads, riserHeight, treadLength, "NOTDEFINED"));
                    }
                    runIter.MoveNext();
                }
                else if (IFCAnyHandleUtil.IsSubTypeOf(component, IFCEntityType.IfcSlab))
                {
                    Element landingElem = (landingIter == null) ? stair : stair.Document.GetElement(landingIter.Current);
                    Element landingElemToUse = (landingElem == null) ? stair : landingElem;
                    ElementId catId = CategoryUtil.GetSafeCategoryId(landingElemToUse);

                    string componentType = IFCValidateEntry.GetValidIFCType(landingElemToUse, IFCAnyHandleUtil.GetEnumerationAttribute(component, "PredefinedType"));
                    // IFCSlabType localLandingType = FloorExporter.GetIFCSlabType(componentType);

                    for (int ii = 0; ii < numFlights - 1; ii++)
                    {
                        IFCAnyHandle representationCopy =
                            ExporterUtil.CopyProductDefinitionShape(exporterIFC, landingElemToUse, catId, componentProdRep);

                        localComponentHnds.Add(IFCInstanceExporter.CreateSlab(file, GUIDUtil.CreateGUID(), ownerHistory,
                            localComponentNames[ii], componentDescription, componentObjectType, componentPlacementHnds[ii], representationCopy,
                            componentElementTag, componentType));
                    }

                    landingIter.MoveNext();
                }
                else if (IFCAnyHandleUtil.IsSubTypeOf(component, IFCEntityType.IfcMember))
                {
                    Element supportElem = (supportIter == null) ? stair : stair.Document.GetElement(supportIter.Current);
                    Element supportElemToUse = (supportElem == null) ? stair : supportElem;
                    ElementId catId = CategoryUtil.GetSafeCategoryId(supportElemToUse);

                    IFCAnyHandle memberType = (supportElemToUse != stair) ? GetMemberTypeHandle(exporterIFC, supportElemToUse) : null;

                    for (int ii = 0; ii < numFlights - 1; ii++)
                    {
                        IFCAnyHandle representationCopy =
                        ExporterUtil.CopyProductDefinitionShape(exporterIFC, supportElemToUse, catId, componentProdRep);

                        localComponentHnds.Add(IFCInstanceExporter.CreateMember(file, GUIDUtil.CreateGUID(), ownerHistory,
                            localComponentNames[ii], componentDescription, componentObjectType, componentPlacementHnds[ii], representationCopy,
                            componentElementTag, "STRINGER"));

                        if (memberType != null)
                            ExporterCacheManager.TypeRelationsCache.Add(memberType, localComponentHnds[ii]);
                    }

                    supportIter.MoveNext();
                }

                for (int ii = 0; ii < numFlights - 1; ii++)
                {
                    if (localComponentHnds[ii] != null)
                    {
                        newComponents[ii].Add(localComponentHnds[ii]);
                        productWrapper.AddElement(null, localComponentHnds[ii], levelInfos[ii], componentECData[compIdx], false);
                    }
                }
                compIdx++;
            }

            // finally add a copy of the container.
            IList<IFCAnyHandle> stairCopyHnds = new List<IFCAnyHandle>();
            for (int ii = 0; ii < numFlights - 1; ii++)
            {
                string stairName = IFCAnyHandleUtil.GetStringAttribute(stairHnd, "Name");
                string stairObjectType = IFCAnyHandleUtil.GetStringAttribute(stairHnd, "ObjectType");
                string stairDescription = IFCAnyHandleUtil.GetStringAttribute(stairHnd, "Description");
                string stairElementTag = IFCAnyHandleUtil.GetStringAttribute(stairHnd, "Tag");
                string stairTypeAsString = IFCAnyHandleUtil.GetEnumerationAttribute(stairHnd, "ShapeType");
                string stairType = GetIFCStairType(stairTypeAsString);

                string containerStairName = stairName + ":" + (ii + 2);
                stairCopyHnds.Add(IFCInstanceExporter.CreateStair(file, GUIDUtil.CreateGUID(), ownerHistory,
                    containerStairName, stairDescription, stairObjectType, stairLocalPlacementHnds[ii], null, stairElementTag, stairType));

                productWrapper.AddElement(stair, stairCopyHnds[ii], levelInfos[ii], null, true);
            }

            for (int ii = 0; ii < numFlights - 1; ii++)
            {
                StairRampContainerInfo stairRampInfo = new StairRampContainerInfo(stairCopyHnds[ii], newComponents[ii],
                    stairLocalPlacementHnds[ii]);
                ExporterCacheManager.StairRampContainerInfoCache.AppendStairRampContainerInfo(stair.Id, stairRampInfo);
            }
        }
        /// <summary>
        /// Export the individual part (IfcBuildingElementPart).
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="partElement">The part element to export.</param>
        /// <param name="geometryElement">The geometry of part.</param>
        /// <param name="productWrapper">The ProductWrapper object.</param>
        public static void ExportPart(ExporterIFC exporterIFC, Element partElement, ProductWrapper productWrapper,
            PlacementSetter placementSetter, IFCAnyHandle originalPlacement, IFCRange range, IFCExtrusionAxes ifcExtrusionAxes,
            Element hostElement, ElementId overrideLevelId, bool asBuildingElement)
        {
            if (!ElementFilteringUtil.IsElementVisible(partElement))
                return;

            Part part = partElement as Part;
            if (part == null)
                return;

            PlacementSetter standalonePlacementSetter = null;
            bool standaloneExport = hostElement == null && !asBuildingElement;

            ElementId partExportLevel = null;
            if (standaloneExport || asBuildingElement)
            {
                partExportLevel = partElement.LevelId;
            }
            else
            {
                if (part.OriginalCategoryId != hostElement.Category.Id)
                    return;
                partExportLevel = hostElement.LevelId;
            }
            if (overrideLevelId != null)
                partExportLevel = overrideLevelId;

            if (ExporterCacheManager.PartExportedCache.HasExported(partElement.Id, partExportLevel))
                return;

            Options options = GeometryUtil.GetIFCExportGeometryOptions();
            View ownerView = partElement.Document.GetElement(partElement.OwnerViewId) as View;
            if (ownerView != null)
                options.View = ownerView;

            GeometryElement geometryElement = partElement.get_Geometry(options);
            if (geometryElement == null)
                return;

            try
            {
                IFCFile file = exporterIFC.GetFile();
                using (IFCTransaction transaction = new IFCTransaction(file))
                {
                    IFCAnyHandle partPlacement = null;
                    if (standaloneExport || asBuildingElement)
                    {
                        Transform orientationTrf = Transform.Identity;
                        standalonePlacementSetter = PlacementSetter.Create(exporterIFC, partElement, null, orientationTrf, partExportLevel);
                        partPlacement = standalonePlacementSetter.LocalPlacement;
                    }
                    else
                    {
                        partPlacement = ExporterUtil.CreateLocalPlacement(file, originalPlacement, null);
                    }

                    bool validRange = (range != null && !MathUtil.IsAlmostZero(range.Start - range.End));

                    SolidMeshGeometryInfo solidMeshInfo;
                    if (validRange)
                    {
                        solidMeshInfo = GeometryUtil.GetSplitClippedSolidMeshGeometry(geometryElement, range);
                        if (solidMeshInfo.GetSolids().Count == 0 && solidMeshInfo.GetMeshes().Count == 0)
                            return;
                    }
                    else
                    {
                        solidMeshInfo = GeometryUtil.GetSplitSolidMeshGeometry(geometryElement);
                    }

                    using (IFCExtrusionCreationData extrusionCreationData = new IFCExtrusionCreationData())
                    {
                        extrusionCreationData.SetLocalPlacement(partPlacement);
                        extrusionCreationData.ReuseLocalPlacement = false;
                        extrusionCreationData.PossibleExtrusionAxes = ifcExtrusionAxes;

                        IList<Solid> solids = solidMeshInfo.GetSolids();
                        IList<Mesh> meshes = solidMeshInfo.GetMeshes();

                        ElementId catId = CategoryUtil.GetSafeCategoryId(partElement);
                        ElementId hostCatId = CategoryUtil.GetSafeCategoryId(hostElement);

                        BodyData bodyData = null;
                        BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true);
                        if (solids.Count > 0 || meshes.Count > 0)
                        {
                            bodyData = BodyExporter.ExportBody(exporterIFC, partElement, catId, ElementId.InvalidElementId, solids, meshes,
                                bodyExporterOptions, extrusionCreationData);
                        }
                        else
                        {
                            IList<GeometryObject> geomlist = new List<GeometryObject>();
                            geomlist.Add(geometryElement);
                            bodyData = BodyExporter.ExportBody(exporterIFC, partElement, catId, ElementId.InvalidElementId, geomlist,
                                bodyExporterOptions, extrusionCreationData);
                        }

                        IFCAnyHandle bodyRep = bodyData.RepresentationHnd;
                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep))
                        {
                            extrusionCreationData.ClearOpenings();
                            return;
                        }

                        IList<IFCAnyHandle> representations = new List<IFCAnyHandle>();
                        representations.Add(bodyRep);

                        IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, geometryElement, Transform.Identity);
                        if (boundingBoxRep != null)
                            representations.Add(boundingBoxRep);

                        IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, representations);

                        IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle();

                        string partGUID = GUIDUtil.CreateGUID(partElement);
                        string partName = NamingUtil.GetNameOverride(partElement, NamingUtil.GetIFCName(partElement));
                        string partDescription = NamingUtil.GetDescriptionOverride(partElement, null);
                        string partObjectType = NamingUtil.GetObjectTypeOverride(partElement, NamingUtil.CreateIFCObjectName(exporterIFC, partElement));
                        string partTag = NamingUtil.GetTagOverride(partElement, NamingUtil.CreateIFCElementId(partElement));

                        IFCAnyHandle ifcPart = null;
                        if (!asBuildingElement)
                        {
                            ifcPart = IFCInstanceExporter.CreateBuildingElementPart(file, partGUID, ownerHistory, partName, partDescription, 
                                partObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, partTag);
                        }
                        else
                        {
                            string ifcEnumType = null;
                            IFCExportType exportType = ExporterUtil.GetExportType(exporterIFC, hostElement, out ifcEnumType);

                            string defaultValue = null;
                            // This replicates old functionality before IFC4 addition, where the default for slab was "FLOOR".
                            // Really the export layer table should be fixed for this case.
                            if (string.IsNullOrWhiteSpace(ifcEnumType) && hostCatId == new ElementId(BuiltInCategory.OST_Floors))
                                ifcEnumType = "FLOOR";
                            ifcEnumType = IFCValidateEntry.GetValidIFCType(hostElement, ifcEnumType, defaultValue);
                            
                            switch (exportType)
                            {
                                case IFCExportType.IfcColumnType:
                                    ifcPart = IFCInstanceExporter.CreateColumn(file, partGUID, ownerHistory, partName, partDescription, partObjectType, 
                                        extrusionCreationData.GetLocalPlacement(), prodRep, partTag, ifcEnumType);
                                    break;
                                case IFCExportType.IfcCovering:
                                    ifcPart = IFCInstanceExporter.CreateCovering(file, partGUID, ownerHistory, partName, partDescription, partObjectType, 
                                        extrusionCreationData.GetLocalPlacement(), prodRep, partTag, ifcEnumType);
                                    break;
                                case IFCExportType.IfcFooting:
                                    ifcPart = IFCInstanceExporter.CreateFooting(file, partGUID, ownerHistory, partName, partDescription, partObjectType, 
                                        extrusionCreationData.GetLocalPlacement(), prodRep, partTag, ifcEnumType);
                                    break;
                                case IFCExportType.IfcPile:
                                    ifcPart = IFCInstanceExporter.CreatePile(file, partGUID, ownerHistory, partName, partDescription, partObjectType,
                                        extrusionCreationData.GetLocalPlacement(), prodRep, partTag, ifcEnumType, null);
                                    break;
                                case IFCExportType.IfcRoof:
                                    ifcPart = IFCInstanceExporter.CreateRoof(file, partGUID, ownerHistory, partName, partDescription, partObjectType, 
                                        extrusionCreationData.GetLocalPlacement(), prodRep, partTag, ifcEnumType);
                                    break;
                                case IFCExportType.IfcSlab:
                                    ifcPart = IFCInstanceExporter.CreateSlab(file, partGUID, ownerHistory, partName, partDescription, partObjectType,
                                        extrusionCreationData.GetLocalPlacement(), prodRep, partTag, ifcEnumType);
                                    break;
                                case IFCExportType.IfcWall:
                                    ifcPart = IFCInstanceExporter.CreateWall(file, partGUID, ownerHistory, partName, partDescription, partObjectType,
                                    extrusionCreationData.GetLocalPlacement(), prodRep, partTag, ifcEnumType);
                                    break;
                                default:
                                    ifcPart = IFCInstanceExporter.CreateBuildingElementProxy(file, partGUID, ownerHistory, partName, partDescription, 
                                        partObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, partTag, null);
                                    break;
                            }
                        }

                        bool containedInLevel = (standaloneExport || asBuildingElement);
                        PlacementSetter whichPlacementSetter = containedInLevel ? standalonePlacementSetter : placementSetter;
                        productWrapper.AddElement(partElement, ifcPart, whichPlacementSetter, extrusionCreationData, containedInLevel);

                        OpeningUtil.CreateOpeningsIfNecessary(ifcPart, partElement, extrusionCreationData, bodyData.OffsetTransform, exporterIFC,
                            extrusionCreationData.GetLocalPlacement(), whichPlacementSetter, productWrapper);

                        //Add the exported part to exported cache.
                        TraceExportedParts(partElement, partExportLevel, standaloneExport || asBuildingElement ? ElementId.InvalidElementId : hostElement.Id);

                        CategoryUtil.CreateMaterialAssociations(exporterIFC, ifcPart, bodyData.MaterialIds);

                        transaction.Commit();
                    }
                }
            }
            finally
            {
                if (standalonePlacementSetter != null)
                    standalonePlacementSetter.Dispose();
            }
        }
示例#15
0
 /// <summary>
 /// Adds openings to an element.
 /// </summary>
 /// <param name="exporterIFC">The exporter.</param>
 /// <param name="elementHandle">The parent handle.</param>
 /// <param name="element">The element.</param>
 /// <param name="plane">The plane.</param>
 /// <param name="scaledWidth">The width.</param>
 /// <param name="range">The range.</param>
 /// <param name="setter">The placement setter.</param>
 /// <param name="localPlacement">The local placement.</param>
 /// <param name="localWrapper">The wrapper.</param>
 public static void AddOpeningsToElement(ExporterIFC exporterIFC, IFCAnyHandle elementHandle, Element element, Plane plane, double scaledWidth,
     IFCRange range, PlacementSetter setter, IFCAnyHandle localPlacement, ProductWrapper localWrapper)
 {
     IList<IFCAnyHandle> elementHandles = new List<IFCAnyHandle>();
     elementHandles.Add(elementHandle);
     AddOpeningsToElement(exporterIFC, elementHandles, null, element, plane, scaledWidth, range, setter, localPlacement, localWrapper);
 }
示例#16
0
        /// <summary>
        /// Creates an opening from a solid.
        /// </summary>
        /// <param name="exporterIFC">The exporter.</param>
        /// <param name="hostObjHnd">The host object handle.</param>
        /// <param name="hostElement">The host element.</param>
        /// <param name="insertElement">The insert element.</param>
        /// <param name="openingGUID">The GUID for the opening, depending on how the opening is created.</param>
        /// <param name="solid">The solid.</param>
        /// <param name="scaledHostWidth">The scaled host width.</param>
        /// <param name="isRecess">True if it is recess.</param>
        /// <param name="extrusionCreationData">The extrusion creation data.</param>
        /// <param name="setter">The placement setter.</param>
        /// <param name="localWrapper">The product wrapper.</param>
        /// <returns>The created opening handle.</returns>
        static public IFCAnyHandle CreateOpening(ExporterIFC exporterIFC, IFCAnyHandle hostObjHnd, Element hostElement, Element insertElement, string openingGUID,
            Solid solid, double scaledHostWidth, bool isRecess, IFCExtrusionCreationData extrusionCreationData, PlacementSetter setter, ProductWrapper localWrapper)
        {
            IFCFile file = exporterIFC.GetFile();

            ElementId catId = CategoryUtil.GetSafeCategoryId(insertElement);

            XYZ prepToWall;
            bool isLinearWall = GetOpeningDirection(hostElement, out prepToWall);
            if (isLinearWall)
            {
                extrusionCreationData.CustomAxis = prepToWall;
                extrusionCreationData.PossibleExtrusionAxes = IFCExtrusionAxes.TryCustom;
            }

            BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true);
            BodyData bodyData = BodyExporter.ExportBody(exporterIFC, insertElement, catId, ElementId.InvalidElementId,
                solid, bodyExporterOptions, extrusionCreationData);

            IFCAnyHandle openingRepHnd = bodyData.RepresentationHnd;
            if (IFCAnyHandleUtil.IsNullOrHasNoValue(openingRepHnd))
            {
                extrusionCreationData.ClearOpenings();
                return null;
            }
            IList<IFCAnyHandle> representations = new List<IFCAnyHandle>();
            representations.Add(openingRepHnd);
            IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, representations);

            IFCAnyHandle openingPlacement = extrusionCreationData.GetLocalPlacement();
            IFCAnyHandle hostObjPlacementHnd = IFCAnyHandleUtil.GetObjectPlacement(hostObjHnd);
            Transform relTransform = ExporterIFCUtils.GetRelativeLocalPlacementOffsetTransform(openingPlacement, hostObjPlacementHnd);

            openingPlacement = ExporterUtil.CreateLocalPlacement(file, hostObjPlacementHnd,
                relTransform.Origin, relTransform.BasisZ, relTransform.BasisX);

            IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle();
            double scaledOpeningLength = extrusionCreationData.ScaledLength;
            string openingObjectType = "Opening";
            if (!MathUtil.IsAlmostZero(scaledHostWidth) && !MathUtil.IsAlmostZero(scaledOpeningLength))
                 openingObjectType = scaledOpeningLength < (scaledHostWidth - MathUtil.Eps()) ? "Recess" : "Opening";
            else
                openingObjectType = isRecess ? "Recess" : "Opening";
            
            string openingName = NamingUtil.GetNameOverride(insertElement, null);
            if (string.IsNullOrEmpty(openingName))
            {
                if (!IFCAnyHandleUtil.IsNullOrHasNoValue(hostObjHnd))
                    openingName = IFCAnyHandleUtil.GetStringAttribute(hostObjHnd, "Name");
                else
                    openingName = NamingUtil.GetNameOverride(hostElement, NamingUtil.CreateIFCObjectName(exporterIFC, hostElement));
            }
            
            IFCAnyHandle openingHnd = IFCInstanceExporter.CreateOpeningElement(file, openingGUID, ownerHistory, openingName, null,
                openingObjectType, openingPlacement, prodRep, null);
            if (ExporterCacheManager.ExportOptionsCache.ExportBaseQuantities)
                PropertyUtil.CreateOpeningQuantities(exporterIFC, openingHnd, extrusionCreationData);

            if (localWrapper != null)
            {
                Element elementForProperties = null;
                if (GUIDUtil.IsGUIDFor(insertElement, openingGUID))
                    elementForProperties = insertElement;

                localWrapper.AddElement(insertElement, openingHnd, setter, extrusionCreationData, true);
            }

            string voidGuid = GUIDUtil.CreateGUID();
            IFCInstanceExporter.CreateRelVoidsElement(file, voidGuid, ownerHistory, null, null, hostObjHnd, openingHnd);
            return openingHnd;
        }
        /// <summary>
        /// Exports the top stories of a multistory ramp.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="ramp">The ramp element.</param>
        /// <param name="numFlights">The number of flights for a multistory ramp.</param>
        /// <param name="rampHnd">The stairs container handle.</param>
        /// <param name="components">The components handles.</param>
        /// <param name="ecData">The extrusion creation data.</param>
        /// <param name="componentECData">The extrusion creation data for the components.</param>
        /// <param name="placementSetter">The placement setter.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        public static void ExportMultistoryRamp(ExporterIFC exporterIFC, Element ramp, int numFlights,
            IFCAnyHandle rampHnd, IList<IFCAnyHandle> components, IList<IFCExtrusionCreationData> componentECData,
            PlacementSetter placementSetter, ProductWrapper productWrapper)
        {
            if (numFlights < 2)
                return;

            double heightNonScaled = GetRampHeight(exporterIFC, ramp);
            if (heightNonScaled < MathUtil.Eps())
                return;

            if (IFCAnyHandleUtil.IsNullOrHasNoValue(rampHnd))
                return;

            IFCAnyHandle localPlacement = IFCAnyHandleUtil.GetObjectPlacement(rampHnd);
            if (IFCAnyHandleUtil.IsNullOrHasNoValue(localPlacement))
                return;

            IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle();

            IFCFile file = exporterIFC.GetFile();

            IFCAnyHandle relPlacement = GeometryUtil.GetRelativePlacementFromLocalPlacement(localPlacement);
            IFCAnyHandle ptHnd = IFCAnyHandleUtil.GetLocation(relPlacement);
            IList<double> origCoords = IFCAnyHandleUtil.GetCoordinates(ptHnd);

            IList<IFCAnyHandle> rampLocalPlacementHnds = new List<IFCAnyHandle>();
            IList<IFCLevelInfo> levelInfos = new List<IFCLevelInfo>();
            for (int ii = 0; ii < numFlights - 1; ii++)
            {
                IFCAnyHandle newLevelHnd = null;

                // We are going to avoid internal scaling routines, and instead scale in .NET.
                double newOffsetUnscaled = 0.0;
                IFCLevelInfo currLevelInfo =
                    placementSetter.GetOffsetLevelInfoAndHandle(heightNonScaled * (ii + 1), 1.0, ramp.Document, out newLevelHnd, out newOffsetUnscaled);
                double newOffsetScaled = UnitUtil.ScaleLength(newOffsetUnscaled);

                levelInfos.Add(currLevelInfo);
                if (levelInfos[ii] == null)
                    levelInfos[ii] = placementSetter.LevelInfo;

                XYZ orig;
                if (ptHnd.HasValue)
                {
                    orig = new XYZ(origCoords[0], origCoords[1], newOffsetScaled);
                }
                else
                {
                    orig = new XYZ(0.0, 0.0, newOffsetScaled);
                }
                rampLocalPlacementHnds.Add(ExporterUtil.CreateLocalPlacement(file, newLevelHnd, orig, null, null));
            }

            IList<List<IFCAnyHandle>> newComponents = new List<List<IFCAnyHandle>>();
            for (int ii = 0; ii < numFlights - 1; ii++)
                newComponents.Add(new List<IFCAnyHandle>());

            int compIdx = 0;
            ElementId catId = CategoryUtil.GetSafeCategoryId(ramp);

            foreach (IFCAnyHandle component in components)
            {
                string componentName = IFCAnyHandleUtil.GetStringAttribute(component, "Name");
                string componentDescription = IFCAnyHandleUtil.GetStringAttribute(component, "Description");
                string componentObjectType = IFCAnyHandleUtil.GetStringAttribute(component, "ObjectType");
                string componentElementTag = IFCAnyHandleUtil.GetStringAttribute(component, "Tag");
                IFCAnyHandle componentProdRep = IFCAnyHandleUtil.GetInstanceAttribute(component, "Representation");

                IList<string> localComponentNames = new List<string>();
                IList<IFCAnyHandle> componentPlacementHnds = new List<IFCAnyHandle>();

                IFCAnyHandle localLocalPlacement = IFCAnyHandleUtil.GetObjectPlacement(component);
                IFCAnyHandle localRelativePlacement =
                    (localLocalPlacement == null) ? null : IFCAnyHandleUtil.GetInstanceAttribute(localLocalPlacement, "RelativePlacement");

                bool isSubRamp = component.IsSubTypeOf(IFCEntityType.IfcRamp.ToString());
                for (int ii = 0; ii < numFlights - 1; ii++)
                {
                    localComponentNames.Add((componentName == null) ? (ii + 2).ToString() : (componentName + ":" + (ii + 2)));
                    if (isSubRamp)
                        componentPlacementHnds.Add(ExporterUtil.CopyLocalPlacement(file, rampLocalPlacementHnds[ii]));
                    else
                        componentPlacementHnds.Add(IFCInstanceExporter.CreateLocalPlacement(file, rampLocalPlacementHnds[ii], localRelativePlacement));
                }

                IList<IFCAnyHandle> localComponentHnds = new List<IFCAnyHandle>();
                if (isSubRamp)
                {
                    string componentType = IFCAnyHandleUtil.GetEnumerationAttribute(component, ExporterCacheManager.ExportOptionsCache.ExportAs4 ? "PredefinedType" : "ShapeType");
                    string localRampType = GetIFCRampType(componentType);

                    for (int ii = 0; ii < numFlights - 1; ii++)
                    {
                        IFCAnyHandle representationCopy =
                            ExporterUtil.CopyProductDefinitionShape(exporterIFC, ramp, catId, componentProdRep);

                        localComponentHnds.Add(IFCInstanceExporter.CreateRamp(file, GUIDUtil.CreateGUID(), ownerHistory,
                            localComponentNames[ii], componentDescription, componentObjectType, componentPlacementHnds[ii], representationCopy,
                            componentElementTag, localRampType));
                    }
                }
                else if (IFCAnyHandleUtil.IsSubTypeOf(component, IFCEntityType.IfcRampFlight))
                {
                    for (int ii = 0; ii < numFlights - 1; ii++)
                    {
                        IFCAnyHandle representationCopy =
                            ExporterUtil.CopyProductDefinitionShape(exporterIFC, ramp, catId, componentProdRep);

                        localComponentHnds.Add(IFCInstanceExporter.CreateRampFlight(file, GUIDUtil.CreateGUID(), ownerHistory,
                            localComponentNames[ii], componentDescription, componentObjectType, componentPlacementHnds[ii], representationCopy,
                            componentElementTag, "NOTDEFINED"));
                    }
                }
                else if (IFCAnyHandleUtil.IsSubTypeOf(component, IFCEntityType.IfcSlab))
                {
                    string componentType = IFCAnyHandleUtil.GetEnumerationAttribute(component, "PredefinedType");
                    IFCSlabType localLandingType = FloorExporter.GetIFCSlabType(componentType);

                    for (int ii = 0; ii < numFlights - 1; ii++)
                    {
                        IFCAnyHandle representationCopy =
                            ExporterUtil.CopyProductDefinitionShape(exporterIFC, ramp, catId, componentProdRep);

                        localComponentHnds.Add(IFCInstanceExporter.CreateSlab(file, GUIDUtil.CreateGUID(), ownerHistory,
                            localComponentNames[ii], componentDescription, componentObjectType, componentPlacementHnds[ii], representationCopy,
                            componentElementTag, localLandingType.ToString()));
                    }
                }
                else if (IFCAnyHandleUtil.IsSubTypeOf(component, IFCEntityType.IfcMember))
                {
                    for (int ii = 0; ii < numFlights - 1; ii++)
                    {
                        IFCAnyHandle representationCopy =
                            ExporterUtil.CopyProductDefinitionShape(exporterIFC, ramp, catId, componentProdRep);

                        localComponentHnds.Add(IFCInstanceExporter.CreateMember(file, GUIDUtil.CreateGUID(), ownerHistory,
                            localComponentNames[ii], componentDescription, componentObjectType, componentPlacementHnds[ii], representationCopy,
                            componentElementTag, "STRINGER"));
                    }
                }

                for (int ii = 0; ii < numFlights - 1; ii++)
                {
                    if (localComponentHnds[ii] != null)
                    {
                        newComponents[ii].Add(localComponentHnds[ii]);
                        productWrapper.AddElement(null, localComponentHnds[ii], levelInfos[ii], componentECData[compIdx], false);
                    }
                }
                compIdx++;
            }

            // finally add a copy of the container.
            IList<IFCAnyHandle> rampCopyHnds = new List<IFCAnyHandle>();
            for (int ii = 0; ii < numFlights - 1; ii++)
            {
                string rampName = IFCAnyHandleUtil.GetStringAttribute(rampHnd, "Name");
                string rampObjectType = IFCAnyHandleUtil.GetStringAttribute(rampHnd, "ObjectType");
                string rampDescription = IFCAnyHandleUtil.GetStringAttribute(rampHnd, "Description");
                string rampElementTag = IFCAnyHandleUtil.GetStringAttribute(rampHnd, "Tag");
                string rampTypeAsString = null;
                if (ExporterCacheManager.ExportOptionsCache.ExportAs4)
                    rampTypeAsString = IFCAnyHandleUtil.GetEnumerationAttribute(rampHnd, "PredefinedType");
                else
                    rampTypeAsString = IFCAnyHandleUtil.GetEnumerationAttribute(rampHnd, "ShapeType");
                string rampType = GetIFCRampType(rampTypeAsString);

                string containerRampName = rampName + ":" + (ii + 2);
                rampCopyHnds.Add(IFCInstanceExporter.CreateRamp(file, GUIDUtil.CreateGUID(), ownerHistory,
                    containerRampName, rampDescription, rampObjectType, rampLocalPlacementHnds[ii], null, rampElementTag, rampType));

                productWrapper.AddElement(ramp, rampCopyHnds[ii], levelInfos[ii], null, true);
            }

            for (int ii = 0; ii < numFlights - 1; ii++)
            {
                StairRampContainerInfo stairRampInfo = new StairRampContainerInfo(rampCopyHnds[ii], newComponents[ii],
                    rampLocalPlacementHnds[ii]);
                ExporterCacheManager.StairRampContainerInfoCache.AppendStairRampContainerInfo(ramp.Id, stairRampInfo);
            }
        }
 /// <summary>
 /// Add a generic element to the wrapper, with associated setter and extrusion data information, and create associated internal property sets if option is set.
 /// </summary>
 /// <param name="element">The element.</param>
 /// <param name="handle">The element handle.</param>
 /// <param name="setter">The placement setter.</param>
 /// <param name="data">The extrusion creation data (can be null.)</param>
 /// <param name="relateToLevel">Relate to the level in the setter, or not.</param>
 public void AddElement(Element element, IFCAnyHandle handle, PlacementSetter setter, IFCExtrusionCreationData data, bool relateToLevel)
 {
    // There is a bug in the internal AddElement that requires us to do a levelInfo null check here.
    IFCLevelInfo levelInfo = setter.LevelInfo;
    bool actuallyRelateToLevel = relateToLevel && (levelInfo != null);
    m_InternalWrapper.AddElement(handle, levelInfo, data, actuallyRelateToLevel);
    if (levelInfo == null && relateToLevel)
       ExporterCacheManager.LevelInfoCache.OrphanedElements.Add(handle);
    RegisterHandleWithElement(element, handle);
 }
示例#19
0
 /// <summary>
 /// Add a generic element to the wrapper, with associated setter and extrusion data information, and create associated internal property sets if option is set.
 /// </summary>
 /// <param name="element">The element.</param>
 /// <param name="handle">The element handle.</param>
 /// <param name="setter">The placement setter.</param>
 /// <param name="data">The extrusion creation data (can be null.)</param>
 /// <param name="relateToLevel">Relate to the level in the setter, or not.</param>
 public void AddElement(Element element, IFCAnyHandle handle, PlacementSetter setter, IFCExtrusionCreationData data, bool relateToLevel)
 {
     m_InternalWrapper.AddElement(handle, setter.LevelInfo, data, relateToLevel);
     RegisterHandleWithElement(element, handle);
 }
        /// <summary>
        /// Gets the offset of the space boundary.
        /// </summary>
        /// <param name="setter">The placement settter.</param>
        /// <returns>The offset.</returns>
        static XYZ GetSpaceBoundaryOffset(PlacementSetter setter)
        {
            IFCAnyHandle localPlacement = setter.LocalPlacement;
            double zOffset = setter.Offset;

            IFCAnyHandle relPlacement = GeometryUtil.GetRelativePlacementFromLocalPlacement(localPlacement);
            if (!IFCAnyHandleUtil.IsNullOrHasNoValue(relPlacement))
            {
                IFCAnyHandle ptHnd = IFCAnyHandleUtil.GetLocation(relPlacement);
                if (!IFCAnyHandleUtil.IsNullOrHasNoValue(ptHnd))
                {
                    IList<double> addToCoords = IFCAnyHandleUtil.GetCoordinates(ptHnd);
                    return new XYZ(addToCoords[0], addToCoords[1], addToCoords[2] + zOffset);
                }
            }

            return new XYZ(0, 0, zOffset);
        }
        private static IFCAnyHandle TryToCreateAsExtrusion(ExporterIFC exporterIFC, 
            Wall wallElement, 
            IList<IList<IFCConnectedWallData>> connectedWalls,
            IList<Solid> solids,
            IList<Mesh> meshes,
            double baseWallElevation, 
            ElementId catId, 
            Curve baseCurve, 
            Curve trimmedCurve,
            Plane wallLCS, 
            double scaledDepth, 
            IFCRange zSpan, 
            IFCRange range, 
            PlacementSetter setter,
            out IList<IFCExtrusionData> cutPairOpenings, 
            out bool isCompletelyClipped, 
            out double scaledFootprintArea, 
            out double scaledLength)
        {
            cutPairOpenings = new List<IFCExtrusionData>();

            IFCAnyHandle bodyRep;
            scaledFootprintArea = 0;

            double unscaledLength = trimmedCurve != null ? trimmedCurve.Length : 0;
            scaledLength = UnitUtil.ScaleLength(unscaledLength);

            XYZ localOrig = wallLCS.Origin;

            // Check to see if the wall has geometry given the specified range.
            if (!WallHasGeometryToExport(wallElement, solids, meshes, range, out isCompletelyClipped))
                return null;

            // This is our major check here that goes into internal code.  If we have enough information to faithfully reproduce
            // the wall as an extrusion with clippings and openings, we will continue.  Otherwise, export it as a BRep.
            if (!CanExportWallGeometryAsExtrusion(wallElement, range))
                return null;

            // extrusion direction.
            XYZ extrusionDir = GetWallHeightDirection(wallElement);

            // create extrusion boundary.
            bool alwaysThickenCurve = IsWallBaseRectangular(wallElement, trimmedCurve);
            
            double unscaledWidth = wallElement.Width;
            IList<CurveLoop> boundaryLoops = GetBoundaryLoopsFromWall(exporterIFC, wallElement, alwaysThickenCurve, trimmedCurve, unscaledWidth);
            if (boundaryLoops == null || boundaryLoops.Count == 0)
                    return null;

            double fullUnscaledLength = baseCurve.Length;
            double unscaledFootprintArea = ExporterIFCUtils.ComputeAreaOfCurveLoops(boundaryLoops);
            scaledFootprintArea = UnitUtil.ScaleArea(unscaledFootprintArea);
            // We are going to do a little sanity check here.  If the scaledFootprintArea is significantly less than the 
            // width * length of the wall footprint, we probably calculated the area wrong, and will abort.
            // This could occur because of a door or window that cuts a corner of the wall (i.e., has no wall material on one side).
            // We want the scaledFootprintArea to be at least (95% of approximateBaseArea - 2 * side wall area).  
            // The "side wall area" is an approximate value that takes into account potential wall joins.  
            // This prevents us from doing extra work for many small walls because of joins.  We'll allow 1' (~30 cm) per side for this.
            double approximateUnscaledBaseArea = unscaledWidth * fullUnscaledLength;
            if (unscaledFootprintArea < (approximateUnscaledBaseArea * .95 - 2 * unscaledWidth))
            {
                // Can't handle the case where we don't have a simple extrusion to begin with.
                if (!alwaysThickenCurve)
                    return null;

                boundaryLoops = GetBoundaryLoopsFromBaseCurve(wallElement, connectedWalls, baseCurve, trimmedCurve, unscaledWidth, scaledDepth);
                if (boundaryLoops == null || boundaryLoops.Count == 0)
                return null;
            }

            // origin gets scaled later.
            double baseWallZOffset = localOrig[2] - ((range == null) ? baseWallElevation : Math.Min(range.Start, baseWallElevation));
            XYZ modifiedSetterOffset = new XYZ(0, 0, setter.Offset + baseWallZOffset);

            IFCAnyHandle baseBodyItemHnd = ExtrusionExporter.CreateExtrudedSolidFromCurveLoop(exporterIFC, null, boundaryLoops, wallLCS,
                extrusionDir, scaledDepth);
            if (IFCAnyHandleUtil.IsNullOrHasNoValue(baseBodyItemHnd))
                return null;

            IFCAnyHandle bodyItemHnd = AddClippingsToBaseExtrusion(exporterIFC, wallElement,
               modifiedSetterOffset, range, zSpan, baseBodyItemHnd, out cutPairOpenings);
            if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyItemHnd))
                return null;
            bool hasClipping = bodyItemHnd.Id != baseBodyItemHnd.Id;

            ElementId matId = HostObjectExporter.GetFirstLayerMaterialId(wallElement);
            IFCAnyHandle styledItemHnd = BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, wallElement.Document,
                baseBodyItemHnd, matId);

            HashSet<IFCAnyHandle> bodyItems = new HashSet<IFCAnyHandle>();
            bodyItems.Add(bodyItemHnd);

            // Check whether wall has opening. If it has, exporting it in the Reference View will need to be in a tessellated geometry that includes the opening cut
            IList<IFCOpeningData> openingDataList = ExporterIFCUtils.GetOpeningData(exporterIFC, wallElement, wallLCS, range);
            bool wallHasOpening = openingDataList.Count > 0;
            BodyExporterOptions options = new BodyExporterOptions(true);

            IFCAnyHandle contextOfItemsBody = exporterIFC.Get3DContextHandle("Body");
            if (!hasClipping)
            {
                // Check whether wall has opening. If it has, exporting it in Reference View will need to be in a tesselated geometry that includes the opening cut
                if (ExporterUtil.IsReferenceView() && wallHasOpening)
                {
                    List<GeometryObject> geomList = new List<GeometryObject>();
                    bodyItems.Clear();       // Since we will change the geometry, clear existing extrusion data first
                    if (solids.Count > 0)
                        foreach (GeometryObject solid in solids)
                            geomList.Add(solid);
                    if (meshes.Count > 0)
                        foreach (GeometryObject mesh in meshes)
                            geomList.Add(mesh);
                    foreach (GeometryObject geom in geomList)
                    {
                        IFCAnyHandle triangulatedBodyItem = BodyExporter.ExportBodyAsTriangulatedFaceSet(exporterIFC, wallElement, options, geom);
                        if (!IFCAnyHandleUtil.IsNullOrHasNoValue(triangulatedBodyItem)) 
                            bodyItems.Add(triangulatedBodyItem);
                    }
                    bodyRep = RepresentationUtil.CreateTessellatedRep(exporterIFC, wallElement, catId, contextOfItemsBody, bodyItems, null);
                }
                else
                    bodyRep = RepresentationUtil.CreateSweptSolidRep(exporterIFC, wallElement, catId, contextOfItemsBody, bodyItems, null);
            }
            else
            {
                // Create TessellatedRep geometry if it is Reference View.
                if (ExporterUtil.IsReferenceView())
                {
                    List<GeometryObject> geomList = new List<GeometryObject>();
                    // The native function AddClippingsToBaseExtrusion will create the IfcBooleanClippingResult entity and therefore here we need to delete it
                    foreach (IFCAnyHandle item in bodyItems)
                    {
                        item.Dispose();     //Still DOES NOT work, the IfcBooleanClippingResult is still orphaned in the IFC file!
                    }
                    bodyItems.Clear();       // Since we will change the geometry, clear existing extrusion data first

                    if (solids.Count > 0)
                        foreach (GeometryObject solid in solids)
                            geomList.Add(solid);
                    if (meshes.Count > 0)
                        foreach (GeometryObject mesh in meshes)
                            geomList.Add(mesh);
                    foreach (GeometryObject geom in geomList)
                    {
                        IFCAnyHandle triangulatedBodyItem = BodyExporter.ExportBodyAsTriangulatedFaceSet(exporterIFC, wallElement, options, geom);
                        if (!IFCAnyHandleUtil.IsNullOrHasNoValue(triangulatedBodyItem)) 
                            bodyItems.Add(triangulatedBodyItem);
                    }
                    bodyRep = RepresentationUtil.CreateTessellatedRep(exporterIFC, wallElement, catId, contextOfItemsBody, bodyItems, null);
                }
                else
                    bodyRep = RepresentationUtil.CreateClippingRep(exporterIFC, wallElement, catId, contextOfItemsBody, bodyItems);
            }

            return bodyRep;
        }
示例#22
0
        /// <summary>
        ///  Creates a new IfcAnnotation object.
        /// </summary>
        /// <param name="exporterIFC">The exporter.</param>
        /// <param name="curveElement">The curve element.</param>
        /// <param name="categoryId">The category id.</param>
        /// <param name="sketchPlaneId">The sketch plane id.</param>
        /// <param name="refPlane">The reference plane.</param>
        /// <param name="curveStyle">The curve style.</param>
        /// <param name="placementSetter">The placemenet setter.</param>
        /// <param name="localPlacement">The local placement.</param>
        /// <param name="repItemHnd">The representation item.</param>
        /// <returns>The handle.</returns>
        static IFCAnyHandle CreateCurveAnnotation(ExporterIFC exporterIFC, Element curveElement, ElementId categoryId, ElementId sketchPlaneId,
            Plane refPlane, IFCAnyHandle curveStyle, PlacementSetter placementSetter, IFCAnyHandle localPlacement, IFCAnyHandle repItemHnd)
        {
            HashSet<IFCAnyHandle> bodyItems = new HashSet<IFCAnyHandle>();
            bodyItems.Add(repItemHnd);
            IFCAnyHandle bodyRepHnd = RepresentationUtil.CreateAnnotationSetRep(exporterIFC, curveElement, categoryId, exporterIFC.Get2DContextHandle(), bodyItems);

            if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRepHnd))
                throw new Exception("Failed to create shape representation.");

            List<IFCAnyHandle> shapes = new List<IFCAnyHandle>();
            shapes.Add(bodyRepHnd);

            IFCFile file = exporterIFC.GetFile();
            IFCAnyHandle prodShapeHnd = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapes);

            XYZ xDir = refPlane.XVec; XYZ zDir = refPlane.Normal; XYZ origin = refPlane.Origin;

            // subtract out level origin if we didn't already before.
            IFCLevelInfo levelInfo = placementSetter.LevelInfo;
            if (levelInfo != null && !MathUtil.IsAlmostEqual(zDir.Z, 1.0))
            {
                zDir -= new XYZ(0, 0, levelInfo.Elevation);
            }

            origin = UnitUtil.ScaleLength(origin);
            IFCAnyHandle relativePlacement = ExporterUtil.CreateAxis(file, origin, zDir, xDir);
            GeometryUtil.SetRelativePlacement(localPlacement, relativePlacement);

            IFCAnyHandle annotation = IFCInstanceExporter.CreateAnnotation(file, GUIDUtil.CreateGUID(), exporterIFC.GetOwnerHistoryHandle(),
                null, null, null, localPlacement, prodShapeHnd);

            return annotation;
        }
示例#23
0
        private static IFCAnyHandle TryToCreateAsExtrusion(ExporterIFC exporterIFC, 
            Wall wallElement, 
            IList<IList<IFCConnectedWallData>> connectedWalls,
            IList<Solid> solids,
            IList<Mesh> meshes,
            double baseWallElevation, 
            ElementId catId, 
            Curve baseCurve, 
            Curve trimmedCurve, 
            Plane plane, 
            double scaledDepth, 
            IFCRange zSpan, 
            IFCRange range, 
            PlacementSetter setter,
            out IList<IFCExtrusionData> cutPairOpenings, 
            out bool isCompletelyClipped, 
            out double scaledFootprintArea, 
            out double scaledLength)
        {
            cutPairOpenings = new List<IFCExtrusionData>();

            IFCAnyHandle bodyRep;
            scaledFootprintArea = 0;

            double unscaledLength = trimmedCurve != null ? trimmedCurve.Length : 0;
            scaledLength = UnitUtil.ScaleLength(unscaledLength);

            XYZ localOrig = plane.Origin;

            // Check to see if the wall has geometry given the specified range.
            if (!WallHasGeometryToExport(wallElement, solids, meshes, range, out isCompletelyClipped))
                return null;

            // This is our major check here that goes into internal code.  If we have enough information to faithfully reproduce
            // the wall as an extrusion with clippings and openings, we will continue.  Otherwise, export it as a BRep.
            if (!CanExportWallGeometryAsExtrusion(wallElement, range))
                return null;

            // extrusion direction.
            XYZ extrusionDir = GetWallHeightDirection(wallElement);

            // create extrusion boundary.
            bool alwaysThickenCurve = IsWallBaseRectangular(wallElement, trimmedCurve);
            
            double unscaledWidth = wallElement.Width;
            IList<CurveLoop> boundaryLoops = GetBoundaryLoopsFromWall(exporterIFC, wallElement, alwaysThickenCurve, trimmedCurve, unscaledWidth);
            if (boundaryLoops == null || boundaryLoops.Count == 0)
                    return null;

            double fullUnscaledLength = baseCurve.Length;
            double unscaledFootprintArea = ExporterIFCUtils.ComputeAreaOfCurveLoops(boundaryLoops);
            scaledFootprintArea = UnitUtil.ScaleArea(unscaledFootprintArea);
            // We are going to do a little sanity check here.  If the scaledFootprintArea is significantly less than the 
            // width * length of the wall footprint, we probably calculated the area wrong, and will abort.
            // This could occur because of a door or window that cuts a corner of the wall (i.e., has no wall material on one side).
            // We want the scaledFootprintArea to be at least (95% of approximateBaseArea - 2 * side wall area).  
            // The "side wall area" is an approximate value that takes into account potential wall joins.  
            // This prevents us from doing extra work for many small walls because of joins.  We'll allow 1' (~30 cm) per side for this.
            double approximateUnscaledBaseArea = unscaledWidth * fullUnscaledLength;
            if (unscaledFootprintArea < (approximateUnscaledBaseArea * .95 - 2 * unscaledWidth))
            {
                // Can't handle the case where we don't have a simple extrusion to begin with.
                if (!alwaysThickenCurve)
                    return null;

                boundaryLoops = GetBoundaryLoopsFromBaseCurve(wallElement, connectedWalls, baseCurve, trimmedCurve, unscaledWidth, scaledDepth);
                if (boundaryLoops == null || boundaryLoops.Count == 0)
                return null;
            }

            // origin gets scaled later.
            XYZ setterOffset = new XYZ(0, 0, setter.Offset + (localOrig[2] - baseWallElevation));

            IFCAnyHandle baseBodyItemHnd = ExtrusionExporter.CreateExtrudedSolidFromCurveLoop(exporterIFC, null, boundaryLoops, plane,
                extrusionDir, scaledDepth);
            if (IFCAnyHandleUtil.IsNullOrHasNoValue(baseBodyItemHnd))
                return null;

            IFCAnyHandle bodyItemHnd = AddClippingsToBaseExtrusion(exporterIFC, wallElement,
               setterOffset, range, zSpan, baseBodyItemHnd, out cutPairOpenings);
            if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyItemHnd))
                return null;

            ElementId matId = HostObjectExporter.GetFirstLayerMaterialId(wallElement);
            IFCAnyHandle styledItemHnd = BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, wallElement.Document,
                baseBodyItemHnd, matId);

            HashSet<IFCAnyHandle> bodyItems = new HashSet<IFCAnyHandle>();
            bodyItems.Add(bodyItemHnd);

            IFCAnyHandle contextOfItemsBody = exporterIFC.Get3DContextHandle("Body");
            if (baseBodyItemHnd.Id == bodyItemHnd.Id)
                bodyRep = RepresentationUtil.CreateSweptSolidRep(exporterIFC, wallElement, catId, contextOfItemsBody, bodyItems, null);
            else
                bodyRep = RepresentationUtil.CreateClippingRep(exporterIFC, wallElement, catId, contextOfItemsBody, bodyItems);

            return bodyRep;
        }