public static DoorWindowInfo CreateWindow(ExporterIFC exporterIFC, FamilyInstance famInst, HostObject hostObj,
                                                  ElementId overrideLevelId, Transform trf)
        {
            DoorWindowInfo doorWindowInfo = new DoorWindowInfo();

            doorWindowInfo.Initialize(false, true, famInst, hostObj);
            doorWindowInfo.CalculateDoorWindowInformation(exporterIFC, famInst, overrideLevelId, trf);

            return(doorWindowInfo);
        }
        /// <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>
        /// 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);
        }
        public static DoorWindowInfo CreateWindow(ExporterIFC exporterIFC, FamilyInstance famInst,  HostObject hostObj,
            ElementId overrideLevelId, Transform trf)
        {
            DoorWindowInfo doorWindowInfo = new DoorWindowInfo();
            doorWindowInfo.Initialize(false, true, famInst, hostObj);
            doorWindowInfo.CalculateDoorWindowInformation(exporterIFC, famInst, overrideLevelId, trf);

            return doorWindowInfo;
        }
        /// <summary>
        /// Creates door panel properties.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="doorWindowInfo">The DoorWindowInfo object.</param>
        /// <param name="familyInstance">The family instance of a door.</param>
        /// <returns>The list of handles created.</returns>
        public static IList<IFCAnyHandle> CreateDoorPanelProperties(ExporterIFC exporterIFC,
           DoorWindowInfo doorWindowInfo, Element familyInstance)
        {
            IFCFile file = exporterIFC.GetFile();
            IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle;

            IList<IFCAnyHandle> doorPanels = new List<IFCAnyHandle>();

            IList<double?> panelDepthList = new List<double?>();
            IList<double?> panelWidthList = new List<double?>();

            IList<string> panelOperationList = new List<string>();
            IList<string> panelPositionList = new List<string>();

            int panelNumber = 1;
            const int maxPanels = 64;  // arbitrary large number to prevent infinite loops.
            for (; panelNumber < maxPanels; panelNumber++)
            {
                string panelDepthCurrString = "PanelDepth" + panelNumber.ToString();
                string panelWidthCurrString = "PanelWidth" + panelNumber.ToString();

                // We will always have at least one panel definition as long as the panelOperation is not
                // NotDefined.

                panelOperationList.Add(GetPanelOperationFromDoorStyleOperation(doorWindowInfo.DoorOperationTypeString));

                // If the panel operation is defined we'll allow no panel position for the 1st panel.
                string panelPosition = GetIFCDoorPanelPosition("", familyInstance, panelNumber);
                if (panelPosition == null)
                {
                    if (panelNumber == 1)
                        panelPosition = GetIFCDoorPanelPosition("", familyInstance, -1);
                    if ((panelPosition == null) && (panelNumber > 1))
                    {
                        panelPositionList.Add("NOTDEFINED");
                        break;
                    }
                }

                if (doorWindowInfo.FlippedX ^ doorWindowInfo.FlippedY)
                    panelPosition = ReverseDoorPanelPosition(panelPosition);

                panelPositionList.Add(panelPosition != null ? panelPosition : "NOTDEFINED");

                double value1 = 0.0, value2 = 0.0;
                bool foundDepth = (ParameterUtil.GetPositiveDoubleValueFromElementOrSymbol(familyInstance, panelDepthCurrString, out value1) != null);
                if (!foundDepth && (panelNumber == 1))
                    foundDepth = (ParameterUtil.GetPositiveDoubleValueFromElementOrSymbol(familyInstance, "PanelDepth", out value1) != null);

                bool foundWidth = (ParameterUtil.GetPositiveDoubleValueFromElementOrSymbol(familyInstance, panelWidthCurrString, out value2) != null);
                if (!foundWidth && (panelNumber == 1))
                    foundWidth = (ParameterUtil.GetPositiveDoubleValueFromElementOrSymbol(familyInstance, "PanelWidth", out value2) != null);

                if (foundDepth && foundWidth)
                {
                    panelDepthList.Add(UnitUtil.ScaleLength(value1));
                    // Make sure value is in [0,1] range.
                    if (value2 < 0.0) value2 = 0.0; else if (value2 > 1.0) value2 = 1.0;
                    panelWidthList.Add(value2);
                }
                else
                {
                    panelDepthList.Add(null);
                    panelWidthList.Add(null);
                }
            }

            string baseDoorPanelName = NamingUtil.GetIFCName(familyInstance);
            for (int panelIndex = 0; (panelIndex < panelNumber - 1); panelIndex++)
            {
                double? currentPanelWidth = null;
                if (panelWidthList[panelIndex].HasValue)
                    currentPanelWidth = (double)panelWidthList[panelIndex];

                string doorPanelName = baseDoorPanelName;
                string doorPanelGUID = GUIDUtil.CreateGUID();
                IFCAnyHandle doorPanel = IFCInstanceExporter.CreateDoorPanelProperties(file, doorPanelGUID, ownerHistory,
                   doorPanelName, null, panelDepthList[panelIndex], panelOperationList[panelIndex],
                   currentPanelWidth, panelPositionList[panelIndex], null);
                doorPanels.Add(doorPanel);
            }

            return doorPanels;
        }
        private static IFCAnyHandle CreateFamilyTypeHandle(ExporterIFC exporterIFC, FamilyTypeInfo typeInfo, DoorWindowInfo doorWindowInfo, 
            IFCAnyHandle bodyRepresentation, IFCAnyHandle planRepresentation,
            Element familyInstance, ElementType familySymbol, ElementType originalFamilySymbol, 
            bool useInstanceGeometry, bool exportParts,
            IFCExportType exportType, string revitObjectType, string ifcEnumType, 
            out HashSet<IFCAnyHandle> propertySets)
        {
            // for many
            propertySets = new HashSet<IFCAnyHandle>();

            IFCFile file = exporterIFC.GetFile();

            IFCAnyHandle repMap2dHnd = null;
            IFCAnyHandle repMap3dHnd = null;

            IList<IFCAnyHandle> repMapList = new List<IFCAnyHandle>();
            {
                IFCAnyHandle origin = null;
                if (bodyRepresentation != null)
                {
                    if (origin == null)
                        origin = ExporterUtil.CreateAxis2Placement3D(file);
                    repMap3dHnd = IFCInstanceExporter.CreateRepresentationMap(file, origin, bodyRepresentation);
                    repMapList.Add(repMap3dHnd);
                }

                if (!IFCAnyHandleUtil.IsNullOrHasNoValue(planRepresentation))
                {
                    if (origin == null)
                        origin = ExporterUtil.CreateAxis2Placement3D(file);
                    repMap2dHnd = IFCInstanceExporter.CreateRepresentationMap(file, origin, planRepresentation);
                    repMapList.Add(repMap2dHnd);
                }
            }

            // We won't allow creating a type if we aren't creating an instance.
            // We won't create the instance if: we are exporting to CV2.0, we have no 2D, 3D, or bounding box geometry, and we aren't exporting parts.
            bool willCreateInstance = !(repMapList.Count == 0 && ExporterCacheManager.ExportOptionsCache.ExportAsCoordinationView2 &&
                !ExporterCacheManager.ExportOptionsCache.ExportBoundingBox && !exportParts);
            if (!willCreateInstance)
                return null;

            IFCAnyHandle typeStyle = null;

            IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle();

            // for Door, Window
            bool paramTakesPrecedence = false; // For Revit, this is currently always false.
            bool sizeable = false;

            string guid = null;
            if (useInstanceGeometry)
            {
                int subElementIndex = ExporterStateManager.GetCurrentRangeIndex();
                if (subElementIndex == 0)
                    guid = GUIDUtil.CreateSubElementGUID(familyInstance, (int)IFCFamilyInstanceSubElements.InstanceAsType);
                else if (subElementIndex <= ExporterStateManager.RangeIndexSetter.GetMaxStableGUIDs())
                    guid = GUIDUtil.CreateSubElementGUID(familyInstance, (int)IFCGenericSubElements.SplitTypeStart + subElementIndex - 1);
                else
                    guid = GUIDUtil.CreateGUID();
            }
            else
                guid = GUIDUtil.CreateGUID(originalFamilySymbol);

            string symId = NamingUtil.CreateIFCElementId(originalFamilySymbol);

            string gentypeName = NamingUtil.GetNameOverride(familySymbol, revitObjectType);
            string gentypeDescription = NamingUtil.GetDescriptionOverride(familySymbol, null);
            string gentypeApplicableOccurrence = NamingUtil.GetOverrideStringValue(familySymbol, "IfcApplicableOccurrence", null);
            string gentypeTag = NamingUtil.GetTagOverride(familySymbol, symId);
            string gentypeElementType = NamingUtil.GetOverrideStringValue(familySymbol, "IfcElementType", revitObjectType);

            // This covers many generic types.  If we can't find it in the list here, do custom exports.
            typeStyle = FamilyExporterUtil.ExportGenericType(exporterIFC, exportType, ifcEnumType, guid,
               gentypeName, gentypeDescription, gentypeApplicableOccurrence, propertySets, repMapList, gentypeTag, gentypeElementType,
               familyInstance, familySymbol);

            // Cover special cases not covered above.
            if (IFCAnyHandleUtil.IsNullOrHasNoValue(typeStyle))
            {
                string symbolTag = NamingUtil.GetTagOverride(familySymbol, NamingUtil.CreateIFCElementId(familySymbol));
                switch (exportType)
                {
                    case IFCExportType.IfcColumnType:
                        {
                            string columnType = "Column";
                            typeStyle = IFCInstanceExporter.CreateColumnType(file, guid, ownerHistory, gentypeName,
                                gentypeDescription, gentypeApplicableOccurrence, propertySets, repMapList, symbolTag,
                                gentypeElementType, GetColumnType(familyInstance, columnType));
                            break;
                        }
                    case IFCExportType.IfcDoorType:
                        {
                            IFCAnyHandle doorLining = DoorWindowUtil.CreateDoorLiningProperties(exporterIFC, familyInstance);
                            if (!IFCAnyHandleUtil.IsNullOrHasNoValue(doorLining))
                                propertySets.Add(doorLining);

                            IList<IFCAnyHandle> doorPanels = DoorWindowUtil.CreateDoorPanelProperties(exporterIFC, doorWindowInfo,
                               familyInstance);
                            propertySets.UnionWith(doorPanels);

                            if (ExporterCacheManager.ExportOptionsCache.ExportAs4)
                            {
                                string doorTypeGUID = GUIDUtil.CreateSubElementGUID(originalFamilySymbol, (int)IFCDoorSubElements.DoorType);
                                typeStyle = IFCInstanceExporter.CreateDoorType(file, doorTypeGUID, ownerHistory, gentypeName,
                                   gentypeDescription, gentypeApplicableOccurrence, propertySets, repMapList, symbolTag,
                                   doorWindowInfo.PreDefinedType, doorWindowInfo.DoorOperationTypeString,
                                   paramTakesPrecedence, doorWindowInfo.UserDefinedOperationType);
                            }
                            else
                            {
                                string doorStyleGUID = GUIDUtil.CreateSubElementGUID(originalFamilySymbol, (int)IFCDoorSubElements.DoorStyle);
                                typeStyle = IFCInstanceExporter.CreateDoorStyle(file, doorStyleGUID, ownerHistory, gentypeName,
                                   gentypeDescription, gentypeApplicableOccurrence, propertySets, repMapList, symbolTag,
                                   doorWindowInfo.DoorOperationTypeString, DoorWindowUtil.GetDoorStyleConstruction(familyInstance),
                                   paramTakesPrecedence, sizeable);
                            }
                            break;
                        }
                    case IFCExportType.IfcSpace:
                        {
                            typeStyle = IFCInstanceExporter.CreateSpaceType(file, guid, ownerHistory, gentypeName,
                               gentypeDescription, gentypeApplicableOccurrence, propertySets, repMapList, symbolTag,
                               gentypeElementType);

                            break;
                        }
                    case IFCExportType.IfcSystemFurnitureElementType:
                        {
                            typeStyle = IFCInstanceExporter.CreateSystemFurnitureElementType(file, guid, ownerHistory, gentypeName,
                               gentypeDescription, gentypeApplicableOccurrence, propertySets, repMapList, symbolTag,
                               gentypeElementType);

                            break;
                        }
                    case IFCExportType.IfcWindowType:
                        {
                            Toolkit.IFCWindowStyleOperation operationType = DoorWindowUtil.GetIFCWindowStyleOperation(originalFamilySymbol);
                            IFCWindowStyleConstruction constructionType = DoorWindowUtil.GetIFCWindowStyleConstruction(familyInstance);

                            IFCAnyHandle windowLining = DoorWindowUtil.CreateWindowLiningProperties(exporterIFC, familyInstance, null);
                            if (!IFCAnyHandleUtil.IsNullOrHasNoValue(windowLining))
                                propertySets.Add(windowLining);

                            IList<IFCAnyHandle> windowPanels =
                               DoorWindowUtil.CreateWindowPanelProperties(exporterIFC, familyInstance, null);
                            propertySets.UnionWith(windowPanels);

                            string windowStyleGUID = GUIDUtil.CreateSubElementGUID(originalFamilySymbol, (int)IFCWindowSubElements.WindowStyle);

                            if (ExporterCacheManager.ExportOptionsCache.ExportAs4)
                            {
                                typeStyle = IFCInstanceExporter.CreateWindowType(file, windowStyleGUID, ownerHistory, gentypeName,
                                   gentypeDescription, gentypeApplicableOccurrence, propertySets, repMapList, symbolTag,
                                   doorWindowInfo.PreDefinedType, DoorWindowUtil.GetIFCWindowPartitioningType(originalFamilySymbol),
                                   paramTakesPrecedence, doorWindowInfo.UserDefinedOperationType);
                            }
                            else
                            {
                                typeStyle = IFCInstanceExporter.CreateWindowStyle(file, windowStyleGUID, ownerHistory, gentypeName,
                                   gentypeDescription, gentypeApplicableOccurrence, propertySets, repMapList, symbolTag,
                                   constructionType, operationType, paramTakesPrecedence, sizeable);
                            }
                            break;
                        }
                    case IFCExportType.IfcBuildingElementProxyType:
                        {
                            Revit.IFC.Common.Enums.IFCEntityType IFCTypeEntity;
                            if (!Enum.TryParse(ifcEnumType, out IFCTypeEntity))
                                break;    // The export type is unknown IFC type entity
                            typeStyle = IFCInstanceExporter.CreateGenericIFCType(IFCTypeEntity, file, guid, ownerHistory, gentypeName,
                                gentypeDescription, gentypeApplicableOccurrence, propertySets, repMapList, symbolTag,
                                gentypeElementType, FamilyExporterUtil.GetPreDefinedType<Toolkit.IFCBuildingElementProxyType>(familyInstance, ifcEnumType).ToString());
                            break;
                        }
                }

                if (IFCAnyHandleUtil.IsNullOrHasNoValue(typeStyle))
                        {
                            if (!IFCAnyHandleUtil.IsNullOrHasNoValue(repMap2dHnd))
                                typeInfo.Map2DHandle = repMap2dHnd;
                            if (!IFCAnyHandleUtil.IsNullOrHasNoValue(repMap3dHnd))
                                typeInfo.Map3DHandle = repMap3dHnd;
                }
            }

            return typeStyle;
        }