/// <summary>
        /// Creates a creator from IFCOpeningData.
        /// </summary>
        /// <param name="exporterIFC">The exporter.</param>
        /// <param name="openingData">The IFCOpeningData.</param>
        /// <param name="scaledHostWidth">The scaled host width.</param>
        /// <param name="hostId">The host id.</param>
        /// <param name="hostHnd">The host handle.</param>
        /// <param name="levelId">The base level id.</param>
        /// <returns>The creator.</returns>
        public static DoorWindowDelayedOpeningCreator Create(ExporterIFC exporterIFC, IFCOpeningData openingData, double scaledHostWidth,
                                                             ElementId hostId, IFCAnyHandle hostHnd, ElementId levelId)
        {
            DoorWindowDelayedOpeningCreator creator = new DoorWindowDelayedOpeningCreator();

            creator.InsertId      = openingData.OpeningElementId;
            creator.HostId        = hostId;
            creator.HostHnd       = hostHnd;
            creator.ExtrusionData = openingData.GetExtrusionData();

            // We can't be guaranteed that the GetOpeningSolids data won't be stale by the time we are ready
            // to use it.  As such, we will clone the geometry here.
            IList <Solid> openingSolids = openingData.GetOpeningSolids();
            IList <Solid> creatorSolids = new List <Solid>();

            foreach (Solid openingSolid in openingSolids)
            {
                creatorSolids.Add(SolidUtils.Clone(openingSolid));
            }

            creator.Solids   = creatorSolids;
            creator.IsRecess = openingData.IsRecess;
            creator.CreatedFromDoorWindowInfo = false;
            creator.ScaledHostWidth           = scaledHostWidth;
            creator.LevelId = levelId;

            if ((creator.ExtrusionData != null && creator.ExtrusionData.Count > 0) || (creator.Solids != null && creator.Solids.Count > 0))
            {
                creator.HasValidGeometry = true;
            }
            return(creator);
        }
        /// <summary>
        /// Copies geometries from another creator.
        /// </summary>
        /// <param name="otherCreator">The other creator.</param>
        public void CopyGeometry(DoorWindowDelayedOpeningCreator otherCreator)
        {
            ExtrusionData   = otherCreator.ExtrusionData;
            Solids          = otherCreator.Solids;
            IsRecess        = otherCreator.IsRecess;
            ScaledHostWidth = otherCreator.ScaledHostWidth;

            if ((ExtrusionData != null && ExtrusionData.Count > 0) || (Solids != null && Solids.Count > 0))
            {
                HasValidGeometry = true;
            }
        }
 /// <summary>
 /// Copy constructor.
 /// </summary>
 /// <param name="orig">The DoorWindowDelayedOpeningCreator.</param>
 public DoorWindowDelayedOpeningCreator(DoorWindowDelayedOpeningCreator orig)
 {
     HasValidGeometry          = orig.HasValidGeometry;
     CreatedFromDoorWindowInfo = orig.CreatedFromDoorWindowInfo;
     PosHingeSide  = orig.PosHingeSide;
     IsRecess      = orig.IsRecess;
     HostId        = orig.HostId;
     InsertId      = orig.InsertId;
     DoorWindowHnd = orig.DoorWindowHnd;
     HostHnd       = orig.HostHnd;
     LevelId       = orig.LevelId;
     ExtrusionData = orig.ExtrusionData;
     Solids        = orig.Solids;
 }
        /// <summary>
        /// Adds a new DoorWindowDelayedOpeningCreator.
        /// </summary>
        /// <param name="creator">The creator.</param>
        public void Add(DoorWindowDelayedOpeningCreator creator)
        {
            if (creator == null)
            {
                return;
            }

            Dictionary <ElementId, DoorWindowDelayedOpeningCreator> existingOpenings = null;

            if (!m_DelayedOpeningCreators.TryGetValue(creator.InsertId, out existingOpenings))
            {
                existingOpenings = new Dictionary <ElementId, DoorWindowDelayedOpeningCreator>();
                m_DelayedOpeningCreators[creator.InsertId] = existingOpenings;
            }

            ElementId levelIdToUse = ExporterCacheManager.ExportOptionsCache.WallAndColumnSplitting ? creator.LevelId : ElementId.InvalidElementId;

            DoorWindowDelayedOpeningCreator oldCreator = null;

            if (existingOpenings.TryGetValue(levelIdToUse, out oldCreator))
            {
                // from DoorWindowInfo has higher priority
                if (oldCreator.CreatedFromDoorWindowInfo)
                {
                    if (!oldCreator.HasValidGeometry && creator.HasValidGeometry)
                    {
                        oldCreator.CopyGeometry(creator);
                    }
                }
                else if (creator.CreatedFromDoorWindowInfo)
                {
                    if (!creator.HasValidGeometry && oldCreator.HasValidGeometry)
                    {
                        creator.CopyGeometry(oldCreator);
                    }
                    existingOpenings[levelIdToUse] = creator;
                }
            }
            else
            {
                existingOpenings[levelIdToUse] = creator;
            }
        }
        /// <summary>
        /// Creates a creator from IFCOpeningData.
        /// </summary>
        /// <param name="exporterIFC">The exporter.</param>
        /// <param name="openingData">The IFCOpeningData.</param>
        /// <param name="scaledHostWidth">The scaled host width.</param>
        /// <param name="hostId">The host id.</param>
        /// <param name="hostHnd">The host handle.</param>
        /// <param name="levelId">The base level id.</param>
        /// <returns>The creator.</returns>
        public static DoorWindowDelayedOpeningCreator Create(ExporterIFC exporterIFC, IFCOpeningData openingData, double scaledHostWidth,
                                                             ElementId hostId, IFCAnyHandle hostHnd, ElementId levelId)
        {
            DoorWindowDelayedOpeningCreator creator = new DoorWindowDelayedOpeningCreator();

            creator.InsertId                  = openingData.OpeningElementId;
            creator.HostId                    = hostId;
            creator.HostHnd                   = hostHnd;
            creator.ExtrusionData             = openingData.GetExtrusionData();
            creator.Solids                    = openingData.GetOpeningSolids();
            creator.IsRecess                  = openingData.IsRecess;
            creator.CreatedFromDoorWindowInfo = false;
            creator.ScaledHostWidth           = scaledHostWidth;
            creator.LevelId                   = levelId;

            if ((creator.ExtrusionData != null && creator.ExtrusionData.Count > 0) || (creator.Solids != null && creator.Solids.Count > 0))
            {
                creator.HasValidGeometry = true;
            }
            return(creator);
        }
        /// <summary>
        /// Adds a new DoorWindowDelayedOpeningCreator.
        /// </summary>
        /// <param name="creator">The creator.</param>
        public void Add(DoorWindowDelayedOpeningCreator creator)
        {
            if (creator == null)
                return;

            Dictionary<ElementId, DoorWindowDelayedOpeningCreator> existingOpenings = null;
            if (!m_DelayedOpeningCreators.TryGetValue(creator.InsertId, out existingOpenings))
            {
                existingOpenings = new Dictionary<ElementId, DoorWindowDelayedOpeningCreator>();
                m_DelayedOpeningCreators[creator.InsertId] = existingOpenings;
            }

            ElementId levelIdToUse = ExporterCacheManager.ExportOptionsCache.WallAndColumnSplitting ? creator.LevelId : ElementId.InvalidElementId;

            DoorWindowDelayedOpeningCreator oldCreator = null;
            if (existingOpenings.TryGetValue(levelIdToUse, out oldCreator))
            {
                // from DoorWindowInfo has higher priority
                if (oldCreator.CreatedFromDoorWindowInfo)
                {
                    if (!oldCreator.HasValidGeometry && creator.HasValidGeometry)
                    {
                        oldCreator.CopyGeometry(creator);
                    }
                }
                else if (creator.CreatedFromDoorWindowInfo)
                {
                    if (!creator.HasValidGeometry && oldCreator.HasValidGeometry)
                    {
                        creator.CopyGeometry(oldCreator);
                    }
                    existingOpenings[levelIdToUse] = creator;
                }
            }
            else
                existingOpenings[levelIdToUse] = creator;
        }
Exemple #7
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);
                }
            }
        }
        /// <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="lcs">The local coordinate system.</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, Transform lcs, double scaledWidth,
            IFCRange range, PlacementSetter setter, IFCAnyHandle localPlacement, ProductWrapper localWrapper)
        {
            IList<IFCOpeningData> openingDataList = ExporterIFCUtils.GetOpeningData(exporterIFC, element, lcs, range);
             IFCFile file = exporterIFC.GetFile();
             IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle;
             foreach (IFCOpeningData openingData in openingDataList)
             {
            Element openingElem = element.Document.GetElement(openingData.OpeningElementId);
            if (openingElem == null)
               openingElem = element;

            bool currentWallIsHost = false;
            FamilyInstance openingFInst = openingElem as FamilyInstance;
            if (openingFInst != null && openingFInst.Host != null)
            {
               if (openingFInst.Host.Id == element.Id)
                  currentWallIsHost = true;
                  //continue;      // If the host is not the current Wall, skip this opening
            }

            // 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);
            bool insertHasHost = false;
            bool insertInThisHost = false;
            if (openingElem is FamilyInstance && element is Wall)
            {
               string ifcEnumType;
               IFCExportInfoPair exportType = ExporterUtil.GetExportType(exporterIFC, openingElem, out ifcEnumType);
               Element instHost = (openingElem as FamilyInstance).Host;
               insertHasHost = (instHost != null);
               insertInThisHost = (insertHasHost && instHost.Id == element.Id);
               isDoorOrWindowOpening =
                  insertInThisHost &&
                  (exportType.ExportInstance == IFCEntityType.IfcDoor ||
                  exportType.ExportType == IFCEntityType.IfcDoorType ||
                  exportType.ExportInstance == IFCEntityType.IfcWindow ||
                  exportType.ExportType == IFCEntityType.IfcWindowType);
            }

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

            // If the opening is "filled" by another element (either a door or window as
            // determined above, or an embedded wall, then we can't use the element GUID
            // for the opening.
            bool canUseElementGUID = (!insertHasHost || insertInThisHost) &&
               !isDoorOrWindowOpening &&
               !(openingElem is Wall);

            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 = CreateOpeningGUID(openingElem, canUseElementGUID);
                  canUseElementGUID = false; // Either it was used above, and therefore is now false, or it was already false.

                  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 = CreateOpeningGUID(openingElem, canUseElementGUID);
               canUseElementGUID = false; // Either it was used above, and therefore is now false, or it was already false.

               CreateOpening(exporterIFC, parentHandle, localPlacement, element, openingElem, openingGUID, extrusionData, lcs, openingData.IsRecess,
                   setter, localWrapper);
            }
             }
        }
 /// <summary>
 /// Creates a creator from IFCOpeningData.
 /// </summary>
 /// <param name="exporterIFC">The exporter.</param>
 /// <param name="openingData">The IFCOpeningData.</param>
 /// <param name="scaledHostWidth">The scaled host width.</param>
 /// <param name="hostId">The host id.</param>
 /// <param name="hostHnd">The host handle.</param>
 /// <param name="levelId">The base level id.</param>
 /// <returns>The creator.</returns>
 public static DoorWindowDelayedOpeningCreator Create(ExporterIFC exporterIFC, IFCOpeningData openingData, double scaledHostWidth, 
     ElementId hostId, IFCAnyHandle hostHnd, ElementId levelId)
 {
     DoorWindowDelayedOpeningCreator creator = new DoorWindowDelayedOpeningCreator();
     creator.InsertId = openingData.OpeningElementId;
     creator.HostId = hostId;
     creator.HostHnd = hostHnd;
     creator.ExtrusionData = openingData.GetExtrusionData();
     creator.Solids = openingData.GetOpeningSolids();
     creator.IsRecess = openingData.IsRecess;
     creator.CreatedFromDoorWindowInfo = false;
     creator.ScaledHostWidth = scaledHostWidth;
     creator.LevelId = levelId;
         
     if ((creator.ExtrusionData != null && creator.ExtrusionData.Count > 0) || (creator.Solids != null && creator.Solids.Count >0))
         creator.HasValidGeometry = true;
     return creator;
 }
        /// <summary>
        /// Creates a creator from DoorWindowInfo.
        /// </summary>
        /// <param name="exporterIFC">The exporter.</param>
        /// <param name="doorWindowInfo">The DoorWindowInfo.</param>
        /// <param name="instanceHandle">The instance handle.</param>
        /// <param name="levelId">The level id.</param>
        /// <returns>The creator.</returns>
        public static DoorWindowDelayedOpeningCreator Create(ExporterIFC exporterIFC, DoorWindowInfo doorWindowInfo, IFCAnyHandle instanceHandle, ElementId levelId)
        {
            if (exporterIFC == null || doorWindowInfo == null)
                return null;

            DoorWindowDelayedOpeningCreator doorWindowDelayedOpeningCreator = null;

            if (doorWindowInfo.HasRealWallHost)
            {
                Document doc = doorWindowInfo.HostObject.Document;
                Wall wall = doorWindowInfo.HostObject as Wall;
                FamilyInstance famInst = doorWindowInfo.InsertInstance;
                ElementId hostId = wall != null ? wall.Id : ElementId.InvalidElementId;
                ElementId instId = famInst != null ? famInst.Id : ElementId.InvalidElementId;

                doorWindowDelayedOpeningCreator = new DoorWindowDelayedOpeningCreator();
                doorWindowDelayedOpeningCreator.HostId = hostId;
                doorWindowDelayedOpeningCreator.InsertId = instId;
                doorWindowDelayedOpeningCreator.PosHingeSide = doorWindowInfo.PosHingeSide;
                doorWindowDelayedOpeningCreator.DoorWindowHnd = instanceHandle;
                doorWindowDelayedOpeningCreator.LevelId = levelId;
                doorWindowDelayedOpeningCreator.CreatedFromDoorWindowInfo = true;

                WallType wallType = doc.GetElement(wall.GetTypeId()) as WallType;
                double unScaledWidth = ((wallType != null) && (wallType.Kind != WallKind.Curtain)) ? wallType.Width : 0.0;
                if (!MathUtil.IsAlmostZero(unScaledWidth))
                {
                    IFCAnyHandle openingHnd = exporterIFC.GetDoorWindowOpeningHandle(instId);
                    if (IFCAnyHandleUtil.IsNullOrHasNoValue(openingHnd))
                    {
                        XYZ cutDir = null;
                        CurveLoop cutLoop = null;
                        try
                        {
                            cutLoop = ExporterIFCUtils.GetInstanceCutoutFromWall(wall.Document, wall, famInst, out cutDir);
                        }
                        catch
                        {
                            cutLoop = null;
                            // Couldn't create opening for door in wall - report as error in log when we create log file.
                        }

                        if (cutLoop != null)
                        {
                            if (doorWindowDelayedOpeningCreator.ExtrusionData == null)
                                doorWindowDelayedOpeningCreator.ExtrusionData = new List<IFCExtrusionData>();

                            IFCExtrusionData extrusionData = new IFCExtrusionData();
                            extrusionData.ExtrusionDirection = cutDir;
                            extrusionData.ScaledExtrusionLength = UnitUtil.ScaleLength(unScaledWidth);
                            extrusionData.AddLoop(cutLoop);
                            doorWindowDelayedOpeningCreator.ScaledHostWidth = UnitUtil.ScaleLength(unScaledWidth);
                            doorWindowDelayedOpeningCreator.ExtrusionData.Add(extrusionData);
                            doorWindowDelayedOpeningCreator.HasValidGeometry = true;
                        }
                        else
                        {
                            // Couldn't create opening for door in wall - report as error in log when we create log file.
                        }
                    }
                }
            }

            return doorWindowDelayedOpeningCreator;
        }
        /// <summary>
        /// Copies geometries from another creator.
        /// </summary>
        /// <param name="otherCreator">The other creator.</param>
        public void CopyGeometry(DoorWindowDelayedOpeningCreator otherCreator)
        {
            ExtrusionData = otherCreator.ExtrusionData;
            Solids = otherCreator.Solids;
            IsRecess = otherCreator.IsRecess;
            ScaledHostWidth = otherCreator.ScaledHostWidth;

            if ((ExtrusionData != null && ExtrusionData.Count > 0) || (Solids != null && Solids.Count > 0))
                HasValidGeometry = true;
        }
 /// <summary>
 /// Copy constructor.
 /// </summary>
 /// <param name="orig">The DoorWindowDelayedOpeningCreator.</param>
 public DoorWindowDelayedOpeningCreator(DoorWindowDelayedOpeningCreator orig)
 {
     HasValidGeometry = orig.HasValidGeometry;
     CreatedFromDoorWindowInfo = orig.CreatedFromDoorWindowInfo;
     PosHingeSide = orig.PosHingeSide;
     IsRecess = orig.IsRecess;
     HostId = orig.HostId;
     InsertId = orig.InsertId;
     DoorWindowHnd = orig.DoorWindowHnd;
     HostHnd = orig.HostHnd;
     LevelId = orig.LevelId;
     ExtrusionData = orig.ExtrusionData;
     Solids = orig.Solids;
 }
        /// <summary>
        /// Creates a creator from DoorWindowInfo.
        /// </summary>
        /// <param name="exporterIFC">The exporter.</param>
        /// <param name="doorWindowInfo">The DoorWindowInfo.</param>
        /// <param name="instanceHandle">The instance handle.</param>
        /// <param name="levelId">The level id.</param>
        /// <returns>The creator.</returns>
        public static DoorWindowDelayedOpeningCreator Create(ExporterIFC exporterIFC, DoorWindowInfo doorWindowInfo, IFCAnyHandle instanceHandle, ElementId levelId)
        {
            if (exporterIFC == null || doorWindowInfo == null)
            {
                return(null);
            }

            DoorWindowDelayedOpeningCreator doorWindowDelayedOpeningCreator = null;

            if (doorWindowInfo.HasRealWallHost)
            {
                Document       doc     = doorWindowInfo.HostObject.Document;
                Wall           wall    = doorWindowInfo.HostObject as Wall;
                FamilyInstance famInst = doorWindowInfo.InsertInstance;
                ElementId      hostId  = wall != null ? wall.Id : ElementId.InvalidElementId;
                ElementId      instId  = famInst != null ? famInst.Id : ElementId.InvalidElementId;

                doorWindowDelayedOpeningCreator                           = new DoorWindowDelayedOpeningCreator();
                doorWindowDelayedOpeningCreator.HostId                    = hostId;
                doorWindowDelayedOpeningCreator.InsertId                  = instId;
                doorWindowDelayedOpeningCreator.PosHingeSide              = doorWindowInfo.PosHingeSide;
                doorWindowDelayedOpeningCreator.DoorWindowHnd             = instanceHandle;
                doorWindowDelayedOpeningCreator.LevelId                   = levelId;
                doorWindowDelayedOpeningCreator.CreatedFromDoorWindowInfo = true;

                WallType wallType      = doc.GetElement(wall.GetTypeId()) as WallType;
                double   unScaledWidth = ((wallType != null) && (wallType.Kind != WallKind.Curtain)) ? wallType.Width : 0.0;
                if (!MathUtil.IsAlmostZero(unScaledWidth))
                {
                    IFCAnyHandle openingHnd = exporterIFC.GetDoorWindowOpeningHandle(instId);
                    if (IFCAnyHandleUtil.IsNullOrHasNoValue(openingHnd))
                    {
                        XYZ       cutDir  = null;
                        CurveLoop cutLoop = null;
                        try
                        {
                            cutLoop = ExporterIFCUtils.GetInstanceCutoutFromWall(wall.Document, wall, famInst, out cutDir);
                        }
                        catch
                        {
                            cutLoop = null;
                            // Couldn't create opening for door in wall - report as error in log when we create log file.
                        }

                        if (cutLoop != null)
                        {
                            if (doorWindowDelayedOpeningCreator.ExtrusionData == null)
                            {
                                doorWindowDelayedOpeningCreator.ExtrusionData = new List <IFCExtrusionData>();
                            }

                            IFCExtrusionData extrusionData = new IFCExtrusionData();
                            extrusionData.ExtrusionDirection    = cutDir;
                            extrusionData.ScaledExtrusionLength = UnitUtil.ScaleLength(unScaledWidth);
                            extrusionData.AddLoop(cutLoop);
                            doorWindowDelayedOpeningCreator.ScaledHostWidth = UnitUtil.ScaleLength(unScaledWidth);
                            doorWindowDelayedOpeningCreator.ExtrusionData.Add(extrusionData);
                            doorWindowDelayedOpeningCreator.HasValidGeometry = true;
                        }
                        else
                        {
                            // Couldn't create opening for door in wall - report as error in log when we create log file.
                        }
                    }
                }
            }

            return(doorWindowDelayedOpeningCreator);
        }
Exemple #14
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="lcs">The local coordinate system.</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,
                                                Transform lcs, double scaledWidth, IFCRange range, PlacementSetter setter,
                                                IFCAnyHandle localPlacement, ProductWrapper localWrapper)
        {
            if (lcs == null && ((curveLoops?.Count ?? 0) > 0))
            {
                // assumption: first curve loop defines the plane.
                Plane hostObjPlane = curveLoops[0].HasPlane() ? curveLoops[0].GetPlane(): null;

                if (hostObjPlane != null)
                {
                    lcs = GeometryUtil.CreateTransformFromPlane(hostObjPlane);
                }
            }

            IList <IFCOpeningData> openingDataList = ExporterIFCUtils.GetOpeningData(exporterIFC,
                                                                                     element, lcs, range);
            IFCFile file = exporterIFC.GetFile();

            int openingIndex = 0;

            foreach (IFCOpeningData openingData in openingDataList)
            {
                openingIndex++;

                Element openingElem = element.Document.GetElement(openingData.OpeningElementId);
                if (openingElem == null)
                {
                    openingElem = element;
                }

                bool           currentWallIsHost = false;
                FamilyInstance openingFInst      = openingElem as FamilyInstance;
                if (openingFInst != null && openingFInst.Host != null)
                {
                    if (openingFInst.Host.Id == element.Id)
                    {
                        currentWallIsHost = true;
                    }
                }

                // 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      = FindParentHandle(elementHandles, curveLoops, extrusionDataList);

                string            predefinedType;
                IFCExportInfoPair exportType = ExporterUtil.GetProductExportType(exporterIFC,
                                                                                 openingElem, out predefinedType);
                bool exportingDoorOrWindow = (exportType.ExportInstance == IFCEntityType.IfcDoor ||
                                              exportType.ExportType == IFCEntityType.IfcDoorType ||
                                              exportType.ExportInstance == IFCEntityType.IfcWindow ||
                                              exportType.ExportType == IFCEntityType.IfcWindowType);

                bool isDoorOrWindowOpening = IsDoorOrWindowOpening(openingElem, element,
                                                                   exportingDoorOrWindow);

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

                IList <Solid> solids     = openingData.GetOpeningSolids();
                int           solidIndex = 0;
                foreach (Solid solid in solids)
                {
                    solidIndex++;

                    using (IFCExtrusionCreationData extrusionCreationData = new IFCExtrusionCreationData())
                    {
                        extrusionCreationData.SetLocalPlacement(ExporterUtil.CreateLocalPlacement(file, localPlacement, null));
                        extrusionCreationData.ReuseLocalPlacement = true;

                        string openingGUID = CreateOpeningGUID(openingElem, range, openingIndex, solidIndex);

                        CreateOpening(exporterIFC, parentHandle, element, openingElem, openingGUID, solid, scaledWidth, openingData.IsRecess, extrusionCreationData,
                                      setter, localWrapper);
                    }
                }

                foreach (IFCExtrusionData extrusionData in extrusionDataList)
                {
                    solidIndex++;

                    if (extrusionData.ScaledExtrusionLength < MathUtil.Eps())
                    {
                        extrusionData.ScaledExtrusionLength = scaledWidth;
                    }

                    string openingGUID = CreateOpeningGUID(openingElem, range, openingIndex, solidIndex);

                    CreateOpening(exporterIFC, parentHandle, localPlacement, element, openingElem,
                                  openingGUID, extrusionData, lcs, openingData.IsRecess, setter, localWrapper);
                }
            }
        }