Example #1
0
        /// <summary>
        /// Finds all related objects in IfcRelAssigns.
        /// </summary>
        /// <param name="ifcRelAssigns">The IfcRelAssigns handle.</param>
        /// <returns>The related objects, or null if not found.</returns>
        static public ICollection <IFCObjectDefinition> ProcessRelatedObjects(IFCAnyHandle ifcRelAssignsOrAggregates)
        {
            try
            {
                ValidateIFCRelAssignsOrAggregates(ifcRelAssignsOrAggregates);
            }
            catch
            {
                //LOG: ERROR: Couldn't find valid IfcRelAssignsToGroup for IfcGroup.
                return(null);
            }

            HashSet <IFCAnyHandle> relatedObjects = IFCAnyHandleUtil.GetAggregateInstanceAttribute
                                                    <HashSet <IFCAnyHandle> >(ifcRelAssignsOrAggregates, "RelatedObjects");

            // Receiving apps need to decide whether to post an error or not.
            if (relatedObjects == null)
            {
                return(null);
            }

            ICollection <IFCObjectDefinition> relatedObjectSet = new HashSet <IFCObjectDefinition>();

            foreach (IFCAnyHandle relatedObject in relatedObjects)
            {
                IFCObjectDefinition objectDefinition = IFCObjectDefinition.ProcessIFCObjectDefinition(relatedObject);
                if (objectDefinition != null)
                {
                    relatedObjectSet.Add(objectDefinition);
                }
            }

            return(relatedObjectSet);
        }
Example #2
0
        /// <summary>
        /// Create a custom sub-category name for an entity.
        /// </summary>
        /// <param name="entity">The entity.</param>
        /// <returns>The category name.</returns>
        /// <remarks>This will also be used to populate the IfcExportAs parameter.</remarks>
        public static string GetCustomCategoryName(IFCObjectDefinition entity)
        {
            IFCEntityType entityType = entity.EntityType;
            string        shapeType  = entity.ShapeType;

            IFCEntityType?typeEntityType = null;
            string        typeShapeType  = null;

            GetAssociatedTypeEntityInfo(entity, out typeEntityType, out typeShapeType);

            if (typeEntityType.HasValue)
            {
                entityType = typeEntityType.Value;
            }
            if (string.IsNullOrWhiteSpace(shapeType) && !string.IsNullOrWhiteSpace(typeShapeType))
            {
                shapeType = typeShapeType;
            }

            string categoryName = entityType.ToString();

            if (!string.IsNullOrWhiteSpace(shapeType))
            {
                categoryName += "." + shapeType;
            }
            return(categoryName);
        }
Example #3
0
        /// <summary>
        /// Finds all related objects in IfcRelAssigns.
        /// </summary>
        /// <param name="relatedTo">The entity receiving the collection of objects and the IFCObjectDefinition will record the inverse relationship</param>
        /// <param name="ifcRelAssignsOrAggregates">The IfcRelAssigns handle.</param>
        /// <returns>The related objects, or null if not found.</returns>
        static public ICollection <IFCObjectDefinition> ProcessRelatedObjects(IFCObjectDefinition relatedTo, IFCAnyHandle ifcRelAssignsOrAggregates)
        {
            try
            {
                ValidateIFCRelAssignsOrAggregates(ifcRelAssignsOrAggregates);
            }
            catch
            {
                //LOG: ERROR: Couldn't find valid IfcRelAssignsToGroup for IfcGroup.
                return(null);
            }

            HashSet <IFCAnyHandle> relatedObjects = IFCAnyHandleUtil.GetAggregateInstanceAttribute
                                                    <HashSet <IFCAnyHandle> >(ifcRelAssignsOrAggregates, "RelatedObjects");

            // Receiving apps need to decide whether to post an error or not.
            if (relatedObjects == null)
            {
                return(null);
            }

            ICollection <IFCObjectDefinition> relatedObjectSet = new HashSet <IFCObjectDefinition>();

            // If relatedTo is an IFCGroup then it will be added to the list of group that the relatedObject is assigned to.
            // else it will become the relatedObject's composing object
            bool relatedIsGroup = relatedTo is IFCGroup;

            foreach (IFCAnyHandle relatedObject in relatedObjects)
            {
                if (relatedObject.Id == relatedTo.Id)
                {
                    Importer.TheLog.LogError(ifcRelAssignsOrAggregates.Id, "An objected is related to itself, ignoring.", false);
                    continue;
                }

                IFCObjectDefinition objectDefinition = IFCObjectDefinition.ProcessIFCObjectDefinition(relatedObject);
                if (objectDefinition != null)
                {
                    if (relatedIsGroup)
                    {
                        objectDefinition.AssignmentGroups.Add(relatedTo as IFCGroup);
                    }
                    else
                    {
                        objectDefinition.Decomposes = relatedTo;
                    }
                    relatedObjectSet.Add(objectDefinition);
                }
            }

            return(relatedObjectSet);
        }
Example #4
0
        private static bool IsColumnLoadBearing(IFCObjectDefinition entity)
        {
            if (entity == null)
            {
                throw new InvalidOperationException("Function called for null entity.");
            }

            // TODO: Figure out load bearing for IfcColumnType.
            if (!(entity is IFCObject))
            {
                return(false);
            }

            IFCObject columnEntity = entity as IFCObject;
            IDictionary <string, IFCPropertySetDefinition> columnPropertySets = columnEntity.PropertySets;
            IFCPropertySetDefinition psetColumnCommonDef = null;

            if (columnPropertySets == null || (!columnPropertySets.TryGetValue("Pset_ColumnCommon", out psetColumnCommonDef)))
            {
                return(false);
            }

            if (!(psetColumnCommonDef is IFCPropertySet))
            {
                throw new InvalidOperationException("Invalid Pset_ColumnCommon class.");
            }

            IFCPropertySet psetColumnCommon = psetColumnCommonDef as IFCPropertySet;
            IDictionary <string, IFCProperty> columnCommonProperties = psetColumnCommon.IFCProperties;
            IFCProperty loadBearingPropertyBase = null;

            if (columnCommonProperties == null || (!columnCommonProperties.TryGetValue("LoadBearing", out loadBearingPropertyBase)))
            {
                return(false);
            }

            if (!(loadBearingPropertyBase is IFCSimpleProperty))
            {
                throw new InvalidOperationException("Invalid Pset_ColumnCommon::LoadBearing property.");
            }

            IFCSimpleProperty        loadBearingProperty = loadBearingPropertyBase as IFCSimpleProperty;
            IList <IFCPropertyValue> propertyValues      = loadBearingProperty.IFCPropertyValues;

            if (propertyValues == null || propertyValues.Count == 0)
            {
                return(false);
            }

            return(propertyValues[0].AsBoolean());
        }
Example #5
0
 /// <summary>
 /// Get the entity type and shape type for the IfcTypeObject of the entity.
 /// </summary>
 /// <param name="entity">The entity.</param>
 /// <param name="typeEntityType">The IfcTypeObject entity type, if it exists.</param>
 /// <param name="typeShapeType">The IfcTypeObject shape type, if it exists.</param>
 private static void GetAssociatedTypeEntityInfo(IFCObjectDefinition entity, out IFCEntityType?typeEntityType, out string typeShapeType)
 {
     typeEntityType = null;
     typeShapeType  = null;
     if (entity is IFCObject)
     {
         IFCObject ifcObject = entity as IFCObject;
         if (ifcObject.TypeObjects != null && ifcObject.TypeObjects.Count > 0)
         {
             IFCTypeObject typeObject = ifcObject.TypeObjects.First();
             typeEntityType = typeObject.EntityType;
             typeShapeType  = typeObject.ShapeType;
         }
     }
 }
Example #6
0
        /// <summary>
        /// Keep track of elements that have been created, for later summary count.
        /// </summary>
        /// <param name="doc">The document.</param>
        /// <param name="objDef">The created entity.</param>
        public void AddCreatedEntity(Document doc, IFCObjectDefinition objDef)
        {
            if (objDef == null)
            {
                return;
            }

            ISet <ElementId> createdElementIds = new HashSet <ElementId>();

            objDef.GetCreatedElementIds(createdElementIds);

            foreach (ElementId createdElementId in createdElementIds)
            {
                Element createdElement = doc.GetElement(createdElementId);
                if (createdElement == null)
                {
                    continue;
                }

                Category elementCategory = createdElement.Category;
                string   catName         = (elementCategory == null) ? "" : elementCategory.Name;

                string typeName = createdElement.GetType().Name;

                CreatedElementsKey mapKey = new CreatedElementsKey(catName, typeName);
                if (m_CreatedElements.ContainsKey(mapKey))
                {
                    m_CreatedElements[mapKey]++;
                }
                else
                {
                    m_CreatedElements.Add(new KeyValuePair <CreatedElementsKey, int>(mapKey, 1));
                }

                m_TotalCreatedElements++;
                UpdateStatusBarAfterCreate();
            }
        }
Example #7
0
        /// <summary>
        /// Import an IFC file into a given document for Reference only.
        /// </summary>
        /// <param name="document">The host document for the import.</param>
        /// <param name="origFullFileName">The full file name of the document.</param>
        /// <param name="options">The list of configurable options for this import.</param>
        public void ReferenceIFC(Document document, string origFullFileName, IDictionary <String, String> options)
        {
            // We need to generate a local file name for all of the intermediate files (the log file, the cache file, and the shared parameters file).
            string localFileName = ImporterIFCUtils.GetLocalFileName(document, origFullFileName);

            if (localFileName == null)
            {
                throw new InvalidOperationException("Could not generate local file name for: " + origFullFileName);
            }

            // An early check, based on the options set - if we are allowed to use an up-to-date existing file on disk, use it.
            // It is possible that the log file may have been created in CreateImporter above,
            // if it is used by an external developer.
            if (TheLog == null)
            {
                m_ImportLog = IFCImportLog.CreateLog(localFileName, "log.html", !m_ImportOptions.DisableLogging);
            }

            Document originalDocument = document;
            Document ifcDocument      = null;

            if (TheOptions.Action == IFCImportAction.Link)
            {
                string linkedFileName = IFCImportFile.GetRevitFileName(localFileName);

                ifcDocument = LoadOrCreateLinkDocument(originalDocument, linkedFileName);
            }
            else
            {
                ifcDocument = originalDocument;
            }

            bool useCachedRevitFile = DocumentUpToDate(ifcDocument, localFileName);

            // In the case where the document is already opened as a link, but it has been updated on disk,
            // give the user a warning and use the cached value.
            if (!useCachedRevitFile && ifcDocument.IsLinked)
            {
                useCachedRevitFile = true;
                Importer.AddDelayedLinkError(BuiltInFailures.ImportFailures.IFCCantUpdateLinkedFile);
            }

            if (!useCachedRevitFile)
            {
                m_ImportCache = IFCImportCache.Create(ifcDocument, localFileName);

                // Limit creating the cache to Link, but may either remove limiting or make it more restrict (reload only) later.
                if (TheOptions.Action == IFCImportAction.Link)
                {
                    TheCache.CreateExistingElementMaps(ifcDocument);
                }

                // TheFile will contain the same value as the return value for this function.
                IFCImportFile.Create(localFileName, m_ImportOptions, ifcDocument);
            }

            if (useCachedRevitFile || IFCImportFile.TheFile != null)
            {
                IFCImportFile theFile = IFCImportFile.TheFile;
                if (theFile != null)
                {
                    if (theFile.IFCProject != null)
                    {
                        IFCObjectDefinition.CreateElement(ifcDocument, theFile.IFCProject);
                    }

                    // Also process any other entities to create.
                    foreach (IFCObjectDefinition objDef in IFCImportFile.TheFile.OtherEntitiesToCreate)
                    {
                        IFCObjectDefinition.CreateElement(ifcDocument, objDef);
                    }

                    theFile.EndImport(ifcDocument, localFileName);
                }

                if (TheOptions.Action == IFCImportAction.Link)
                {
                    // If we have an original Revit link file name, don't create a new RevitLinkType -
                    // we will use the existing one.
                    bool      useExistingType = (TheOptions.RevitLinkFileName != null);
                    ElementId revitLinkTypeId = IFCImportFile.LinkInFile(origFullFileName, localFileName, ifcDocument, originalDocument, useExistingType, !useCachedRevitFile);
                }
            }

            if (m_ImportCache != null)
            {
                m_ImportCache.Reset(ifcDocument);
            }
        }
Example #8
0
        /// <summary>
        /// Import an IFC file into a given document for Reference only.
        /// </summary>
        /// <param name="document">The host document for the import.</param>
        /// <param name="fullFileName">The full file name of the document.</param>
        /// <param name="options">The list of configurable options for this import.</param>
        public void ReferenceIFC(Document document, string fullFileName, IDictionary <String, String> options)
        {
            // An early check, based on the options set - if we are allowed to use an up-to-date existing file on disk, use it.
            m_ImportLog = IFCImportLog.CreateLog(fullFileName, "log.html");

            Document originalDocument = document;
            Document ifcDocument      = null;

            if (TheOptions.Action == IFCImportAction.Link)
            {
                string linkedFileName = IFCImportFile.GetRevitFileName(fullFileName);

                ifcDocument = LoadOrCreateLinkDocument(originalDocument, linkedFileName);
                if (ifcDocument == null)
                {
                    return;
                }
            }
            else
            {
                ifcDocument = originalDocument;
            }

            bool useCachedRevitFile = DocumentUpToDate(ifcDocument, fullFileName);

            // In the case where the document is already opened as a link, but it has been updated on disk,
            // give the user a warning and use the cached value.
            if (!useCachedRevitFile && ifcDocument.IsLinked)
            {
                useCachedRevitFile = true;
                Importer.AddDelayedLinkError(BuiltInFailures.ImportFailures.IFCCantUpdateLinkedFile);
            }

            if (!useCachedRevitFile)
            {
                m_ImportCache = IFCImportCache.Create(ifcDocument, fullFileName);

                // Limit creating the cache to Link, but may either remove limiting or make it more restrict (reload only) later.
                if (TheOptions.Action == IFCImportAction.Link)
                {
                    TheCache.CreateExistingElementMaps(ifcDocument);
                }

                // TheFile will contain the same value as the return value for this function.
                IFCImportFile.Create(fullFileName, m_ImportOptions, ifcDocument);
            }

            if (useCachedRevitFile || IFCImportFile.TheFile != null)
            {
                IFCImportFile theFile = IFCImportFile.TheFile;
                if (theFile != null)
                {
                    if (theFile.IFCProject != null)
                    {
                        IFCObjectDefinition.CreateElement(ifcDocument, theFile.IFCProject);
                    }

                    // Also process any other entities to create.
                    foreach (IFCObjectDefinition objDef in IFCImportFile.TheFile.OtherEntitiesToCreate)
                    {
                        IFCObjectDefinition.CreateElement(ifcDocument, objDef);
                    }

                    theFile.EndImport(ifcDocument, fullFileName);
                }

                if (TheOptions.Action == IFCImportAction.Link)
                {
                    // If we have an original Revit link file name, don't create a new RevitLinkType -
                    // we will use the existing one.
                    bool      useExistingType = (TheOptions.RevitLinkFileName != null);
                    ElementId revitLinkTypeId = IFCImportFile.LinkInFile(fullFileName, ifcDocument, originalDocument, useExistingType, !useCachedRevitFile);
                }
            }

            if (m_ImportCache != null)
            {
                m_ImportCache.Reset(ifcDocument);
            }
        }
Example #9
0
        /// <summary>
        /// Get the top-level Built-in category id for an IFC entity.
        /// </summary>
        /// <param name="doc">The doument.</param>
        /// <param name="entity">The entity.</param>
        /// <param name="gstyleId">The graphics style, if the returned category is not top level.  This allows shapes to have their visibility controlled by the sub-category.</param>
        /// <returns>The element id for the built-in category.</returns>
        public static ElementId GetCategoryIdForEntity(Document doc, IFCObjectDefinition entity, out ElementId gstyleId)
        {
            gstyleId = ElementId.InvalidElementId;

            IFCEntityType entityType = entity.EntityType;

            IFCEntityType?typeEntityType = null;
            string        typeShapeType  = null;

            GetAssociatedTypeEntityInfo(entity, out typeEntityType, out typeShapeType);

            // Use the IfcTypeObject shape type if the IfcElement shape type is either null, empty, white space, or not defined.
            string shapeType = entity.ShapeType;

            if ((string.IsNullOrWhiteSpace(shapeType) || (string.Compare(shapeType, "NOTDEFINED", true) == 0)) &&
                !string.IsNullOrWhiteSpace(typeShapeType))
            {
                shapeType = typeShapeType;
            }

            // Set "special" shape types
            switch (entityType)
            {
            case IFCEntityType.IfcColumn:
            case IFCEntityType.IfcColumnType:
                if (IsColumnLoadBearing(entity))
                {
                    shapeType = "[LoadBearing]";
                }
                break;
            }

            ElementId catElemId = GetCategoryElementId(entityType, shapeType);

            // If we didn't find a category, or if we found the generic model category, try again with the IfcTypeObject, if there is one.
            if (catElemId == ElementId.InvalidElementId || catElemId.IntegerValue == (int)BuiltInCategory.OST_GenericModel)
            {
                if (typeEntityType.HasValue)
                {
                    catElemId = GetCategoryElementId(typeEntityType.Value, shapeType);
                }
            }

            Category subCategory = null;

            if (catElemId.IntegerValue == (int)BuiltInCategory.OST_GenericModel)
            {
                string subCategoryName = GetCustomCategoryName(entity);
                if (!string.IsNullOrWhiteSpace(subCategoryName))
                {
                    IDictionary <string, Category> createdSubcategories = Importer.TheCache.CreatedSubcategories;
                    if (!createdSubcategories.TryGetValue(subCategoryName, out subCategory))
                    {
                        // Category may have been created by a previous action (probably a previous import).  Look first.
                        try
                        {
                            CategoryNameMap subCategories = Importer.TheCache.GenericModelsCategory.SubCategories;
                            subCategory = subCategories.get_Item(subCategoryName);
                        }
                        catch
                        {
                            subCategory = null;
                        }

                        if (subCategory == null)
                        {
                            subCategory = Importer.TheCache.DocumentCategories.NewSubcategory(Importer.TheCache.GenericModelsCategory, subCategoryName);
                            SetMaterialForSpacesAndOpenings(doc, entity.Id, subCategory, subCategoryName);
                        }

                        createdSubcategories[subCategoryName] = subCategory;
                    }

                    GraphicsStyle graphicsStyle = subCategory.GetGraphicsStyle(GraphicsStyleType.Projection);
                    if (graphicsStyle != null)
                    {
                        gstyleId = graphicsStyle.Id;
                    }
                }
            }
            else if (catElemId == ElementId.InvalidElementId)
            {
                catElemId = new ElementId(BuiltInCategory.OST_GenericModel);

                // Top level entities that are OK to be here.
                if (entityType != IFCEntityType.IfcProject &&
                    entityType != IFCEntityType.IfcBuilding &&
                    entityType != IFCEntityType.IfcBuildingStorey &&
                    entityType != IFCEntityType.IfcElementAssembly)
                {
                    string msg = "Setting IFC entity ";
                    if (string.IsNullOrWhiteSpace(shapeType))
                    {
                        msg = entityType.ToString();
                    }
                    else
                    {
                        msg = entityType.ToString() + "." + shapeType;
                    }

                    if (typeEntityType.HasValue)
                    {
                        msg += " (" + typeEntityType.Value.ToString() + ")";
                    }

                    msg += " to Generic Models.";
                    IFCImportFile.TheLog.LogWarning(entity.Id, msg, true);
                }
            }

            Category categoryToCheck = null;

            if (catElemId.IntegerValue < 0)
            {
                categoryToCheck = Importer.TheCache.DocumentCategories.get_Item((BuiltInCategory)catElemId.IntegerValue);
            }
            else
            {
                categoryToCheck = subCategory;
            }

            if (categoryToCheck != null)
            {
                // We'll assume that a negative value means a built-in category.  It may still be a sub-category, in which case we need to get the parent category and assign the gstyle.
                // We could optimize this, but this is safer.
                Category parentCategory = categoryToCheck.Parent;
                if (parentCategory != null)
                {
                    catElemId = parentCategory.Id;
                }

                // Not already set by subcategory.
                if (gstyleId == ElementId.InvalidElementId)
                {
                    GraphicsStyle graphicsStyle = categoryToCheck.GetGraphicsStyle(GraphicsStyleType.Projection);
                    if (graphicsStyle != null)
                    {
                        gstyleId = graphicsStyle.Id;
                    }
                }
            }

            return(catElemId);
        }
Example #10
0
        public void ImportIFC(ImporterIFC importer)
        {
            TheImporter = this;

            IDictionary <String, String> options = importer.GetOptions();

            TheOptions = m_ImportOptions = IFCImportOptions.Create(options);

            // An early check, based on the options set - if we are allowed to use an up-to-date existing file on disk, use it.
            try
            {
                string revitFileName = IFCImportFile.GetRevitFileName(importer.FullFileName);
                if (!TheOptions.ForceImport && !NeedsReload(importer.FullFileName, revitFileName))
                {
                    return;
                }

                // Clear the category mapping table, to force reload of options.
                IFCCategoryUtil.Clear();

                if (TheOptions.Intent != IFCImportIntent.Reference)
                {
                    IFCImportFile.Import(importer);
                }
                else
                {
                    Document originalDocument = importer.Document;
                    Document ifcDocument      = null;

                    if (TheOptions.Action == IFCImportAction.Link)
                    {
                        string linkedFileName = IFCImportFile.GetRevitFileName(importer.FullFileName);

                        ifcDocument = LoadOrCreateLinkDocument(originalDocument, linkedFileName);
                        if (ifcDocument == null)
                        {
                            return;
                        }
                    }
                    else
                    {
                        ifcDocument = originalDocument;
                    }

                    bool useCachedRevitFile = DocumentUpToDate(ifcDocument, importer.FullFileName);

                    // In the case where the document is already opened as a link, but it has been updated on disk,
                    // give the user a warning and use the cached value.
                    if (!useCachedRevitFile && ifcDocument.IsLinked)
                    {
                        useCachedRevitFile = true;
                        Importer.AddDelayedLinkError(BuiltInFailures.ImportFailures.IFCCantUpdateLinkedFile);
                    }

                    if (!useCachedRevitFile)
                    {
                        m_ImportCache = IFCImportCache.Create(ifcDocument, importer.FullFileName);

                        // Limit creating the cache to Link, but may either remove limiting or make it more restrict (reload only) later.
                        if (TheOptions.Action == IFCImportAction.Link)
                        {
                            TheCache.CreateExistingElementMaps(ifcDocument);
                        }

                        // TheFile will contain the same value as the return value for this function.
                        IFCImportFile.Create(importer.FullFileName, m_ImportOptions, ifcDocument);
                    }

                    if (useCachedRevitFile || IFCImportFile.TheFile != null)
                    {
                        if (IFCImportFile.TheFile != null)
                        {
                            if (IFCImportFile.TheFile.IFCProject != null)
                            {
                                IFCObjectDefinition.CreateElement(ifcDocument, IFCImportFile.TheFile.IFCProject);
                            }
                            IFCImportFile.TheFile.EndImport(ifcDocument, importer.FullFileName);
                        }

                        if (TheOptions.Action == IFCImportAction.Link)
                        {
                            // If we have an original Revit link file name, don't create a new RvtLinkSymbol -
                            // we will use the existing one.
                            bool useExistingType = (TheOptions.RevitLinkFileName != null);
                            IFCImportFile.LinkInFile(importer.FullFileName, ifcDocument, originalDocument, useExistingType, !useCachedRevitFile);
                        }
                    }

                    m_ImportCache.Reset(ifcDocument);
                }
            }
            catch (Exception ex)
            {
                if (IFCImportFile.TheFile != null)
                {
                    IFCImportFile.TheFile.Log.LogError(-1, ex.Message, false);
                }
            }
            finally
            {
                if (IFCImportFile.TheFile != null)
                {
                    IFCImportFile.TheFile.Close();
                }
            }
        }