Esempio n. 1
0
        private IList <GeometryObject> GetOrCloneGeometry(Document doc, IFCObjectDefinition objectDefinition)
        {
            if (!(objectDefinition is IFCBuildingElementPart))
            {
                return(objectDefinition.CreatedGeometry);
            }

            // In the case of IFCBuildingElementPart, we want the container to have a copy of the geometry in the category of the parent,
            // as otherwise the geometry will be controlled by default by the Parts category instead of the parent category.
            IList <IFCSolidInfo> clonedGeometry = IFCElement.CloneElementGeometry(doc, objectDefinition as IFCProduct, this, false);

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

            IList <GeometryObject> geomObjs = new List <GeometryObject>();

            foreach (IFCSolidInfo solid in clonedGeometry)
            {
                geomObjs.Add(solid.GeometryObject);
            }

            return(geomObjs);
        }
Esempio n. 2
0
        /// <summary>
        /// Add a double parameter to an element.
        /// </summary>
        /// <param name="doc">The document.</param>
        /// <param name="element">The element.</param>
        /// <param name="category">The category of the element.</param>
        /// <param name="parameterName">The parameter name.</param>
        /// <param name="specTypeId">Identifier of the parameter spec (e.g. length)</param>
        /// <param name="unitsTypeId">Identifier of the unscaled parameter units (e.g. mm)</param>
        /// <param name="parameterValue">The parameter value, scaled into document units.</param>
        /// <param name="parameterSetId">The id of the containing parameter set, for reporting errors.</param>
        /// <returns>True if the parameter was successfully added, false otherwise.</returns>
        public static bool AddParameterDouble(Document doc, Element element, Category category,
                                              IFCObjectDefinition objDef, string parameterName, ForgeTypeId specTypeId,
                                              ForgeTypeId unitsTypeId, double parameterValue, int parameterSetId)
        {
            if (doc == null || element == null || category == null)
            {
                return(false);
            }

            unitsTypeId = CalculateUnitsTypeId(unitsTypeId, specTypeId);
            bool?processedParameter = Importer.TheProcessor.ProcessParameter(objDef.Id,
                                                                             specTypeId, unitsTypeId, parameterSetId, parameterName, parameterValue);

            if (processedParameter.HasValue)
            {
                return(processedParameter.Value);
            }

            Parameter parameter = AddParameterBase(doc, element, category, parameterName, parameterSetId, specTypeId);

            if (parameter == null)
            {
                return(false);
            }

            parameter.Set(parameterValue);
            return(true);
        }
Esempio n. 3
0
        /// <summary>
        /// Create one or more elements
        /// </summary>
        /// <param name="doc">The document being populated.</param>
        /// <returns>The primary element associated with the IFCObjectDefinition, or InvalidElementId if it failed.</returns>
        public static ElementId CreateElement(Document doc, IFCObjectDefinition objDef)
        {
            // This would be a good place to check 'objDef.GlobalId'.

            ElementId createdElementId = objDef.CreatedElementId;

            try
            {
                if ((createdElementId == ElementId.InvalidElementId) && objDef.IsValidForCreation)
                {
                    ElementId gstyleId;
                    objDef.CategoryId        = IFCCategoryUtil.GetCategoryIdForEntity(doc, objDef, out gstyleId);
                    objDef.m_GraphicsStyleId = gstyleId;

                    if (objDef is IFCObject)
                    {
                        IFCObject asObject = objDef as IFCObject;
                        foreach (IFCTypeObject typeObject in asObject.TypeObjects)
                        {
                            IFCObjectDefinition.CreateElement(doc, typeObject);
                        }
                    }

                    objDef.Create(doc);
                    objDef.CreateParameters(doc);
                    createdElementId = objDef.CreatedElementId;
                    IFCImportFile.TheLog.AddCreatedEntity(doc, objDef);

                    if (IFCImportFile.CleanEntitiesAfterCreate)
                    {
                        objDef.CleanEntity();
                    }
                }
            }
            catch (Exception ex)
            {
                if (objDef != null)
                {
                    objDef.IsValidForCreation = false;
                    IFCImportFile.TheLog.LogCreationError(objDef, ex.Message, false);
                }
            }
            return(createdElementId);
        }
Esempio n. 4
0
        /// <summary>
        /// Add a string parameter to an element.
        /// </summary>
        /// <param name="doc">The document.</param>
        /// <param name="element">The element.</param>
        /// <param name="objDef">The IFCObjectDefinition that created the element.</param>
        /// <param name="name">The enum corresponding to the parameter name.</param>
        /// <param name="parameterValue">The parameter value.</param>
        /// <param name="parameterSetId">The id of the containing parameter set, for reporting errors.</param>
        /// <returns>True if the parameter was successfully added, false otherwise.</returns>
        public static bool AddParameterString(Document doc, Element element, IFCObjectDefinition objDef, IFCSharedParameters name, string parameterValue, int parameterSetId)
        {
            if (objDef == null)
            {
                return(false);
            }

            string parameterName = objDef.GetSharedParameterName(name);

            Parameter parameter = AddParameterBase(doc, element, parameterName, parameterSetId, ParameterType.Text);

            if (parameter == null)
            {
                return(false);
            }

            parameter.Set(parameterValue);
            return(true);
        }
Esempio n. 5
0
        /// <summary>
        /// Creates or populates Revit elements based on the information contained in this class.
        /// </summary>
        /// <param name="doc">The document.</param>
        protected virtual void TraverseSubElements(Document doc)
        {
            IList <ElementId> subElementIds = new List <ElementId>();

            if (ComposedObjectDefinitions != null)
            {
                foreach (IFCObjectDefinition objectDefinition in ComposedObjectDefinitions)
                {
                    IFCObjectDefinition.CreateElement(doc, objectDefinition);
                    if (objectDefinition.CreatedElementId != ElementId.InvalidElementId)
                    {
                        subElementIds.Add(objectDefinition.CreatedElementId);
                    }
                }
            }

            if (GroupSubElements())
            {
                if (subElementIds.Count > 0)
                {
                    if (CreatedElementId != ElementId.InvalidElementId)
                    {
                        subElementIds.Add(CreatedElementId);
                    }

                    // We aren't yet actually grouping the elements.  DirectShape doesn't support grouping, and
                    // the Group element doesn't support adding parameters.  For now, we will create a DirectShape that "forgets"
                    // the association, which is good enough for link.
                    DirectShape directShape = IFCElementUtil.CreateElement(doc, CategoryId, Importer.ImportAppGUID(), GlobalId);
                    //Group group = doc.Create.NewGroup(subElementIds);
                    if (directShape != null)
                    {
                        CreatedElementId = directShape.Id;
                    }
                    else
                    {
                        IFCImportFile.TheLog.LogCreationError(this, null, false);
                    }
                }
            }
        }
        /// <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)
            {
                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;
        }
Esempio n. 7
0
        /// <summary>
        /// Create a property set for a given element.
        /// </summary>
        /// <param name="doc">The document.</param>
        /// <param name="element">The element being created.</param>
        /// <param name="parameterGroupMap">The parameters of the element.  Cached for performance.</param>
        /// <returns>The name of the property set created, if it was created, and a Boolean value if it should be added to the property set list.</returns>
        public override Tuple <string, bool> CreatePropertySet(Document doc, Element element, IFCObjectDefinition objDef, IFCParameterSetByGroup parameterGroupMap)
        {
            IDictionary <string, IFCData> parametersToAdd = new Dictionary <string, IFCData>();
            Category category = IFCPropertySet.GetCategoryForParameterIfValid(element, Id);

            foreach (KeyValuePair <Tuple <string, ForgeTypeId, AllowedValues>, double> property in DoubleProperties)
            {
                string    name = property.Key.Item1;
                Parameter existingParameter = null;
                if (!parameterGroupMap.TryFindParameter(name, out existingParameter))
                {
                    ForgeTypeId valueType = property.Key.Item2;
                    // If we aren't scaling values, all length values have come from Attributes
                    // and so will always be in feet.
                    ForgeTypeId unitType = (!Importer.TheProcessor.ScaleValues && valueType == SpecTypeId.Length) ?
                                           UnitTypeId.Feet : null;
                    IFCPropertySet.AddParameterDouble(doc, element, category, objDef, name, valueType, unitType, property.Value, Id);
                    continue;
                }

                switch (existingParameter.StorageType)
                {
                case StorageType.String:
                    existingParameter.Set(property.Value.ToString());
                    break;

                case StorageType.Double:
                    existingParameter.Set(property.Value);
                    break;

                default:
                    Importer.TheLog.LogError(Id, "couldn't create parameter: " + name + " of storage type: " + existingParameter.StorageType.ToString(), false);
                    break;
                }
            }

            foreach (KeyValuePair <string, string> property in StringProperties)
            {
                string    name = property.Key;
                Parameter existingParameter = null;
                if (!parameterGroupMap.TryFindParameter(name, out existingParameter))
                {
                    IFCPropertySet.AddParameterString(doc, element, category, objDef, property.Key, property.Value, Id);
                    continue;
                }

                switch (existingParameter.StorageType)
                {
                case StorageType.String:
                    existingParameter.Set(property.Value);
                    break;

                default:
                    Importer.TheLog.LogError(Id, "couldn't create parameter: " + name + " of storage type: " + existingParameter.StorageType.ToString(), false);
                    break;
                }
            }

            return(Tuple.Create("\"" + EntityType.ToString() + "\"", false));
        }
Esempio n. 8
0
        /// <summary>
        /// Create a quantity for a given element.
        /// </summary>
        /// <param name="doc">The document.</param>
        /// <param name="element">The element being created.</param>
        /// <param name="category">The element's category.</param>
        /// <param name="parameterMap">The parameters of the element.  Cached for performance.</param>
        /// <param name="propertySetName">The name of the containing property set.</param>
        /// <param name="createdParameters">The names of the created parameters.</param>
        public override void Create(Document doc, Element element, Category category, IFCObjectDefinition objDef, IFCParameterSetByGroup parameterGroupMap, string propertySetName, ISet <string> createdParameters)
        {
            double baseValue          = 0.0;
            IFCDataPrimitiveType type = Value.PrimitiveType;

            switch (type)
            {
            case IFCDataPrimitiveType.Double:
                baseValue = Value.AsDouble();
                break;

            case IFCDataPrimitiveType.Integer:
                // This case isn't valid, but could happen when repairing a file
                Importer.TheLog.LogWarning(Id, "Unexpected integer parameter type, repairing.", false);
                baseValue = Value.AsInteger();
                break;

            default:
                Importer.TheLog.LogError(Id, "Invalid parameter type: " + type.ToString() + " for IfcPhysicalSimpleQuantity", false);
                return;
            }

            double doubleValueToUse = Importer.TheProcessor.ScaleValues ?
                                      IFCUnit?.Convert(baseValue) ?? baseValue :
                                      baseValue;

            Parameter existingParameter     = null;
            string    originalParameterName = propertySetName + "." + Name;
            string    parameterName         = originalParameterName;

            if (!parameterGroupMap.TryFindParameter(parameterName, out existingParameter))
            {
                int parameterNameCount = 2;
                while (createdParameters.Contains(parameterName))
                {
                    parameterName = originalParameterName + " " + parameterNameCount;
                    parameterNameCount++;
                }
                if (parameterNameCount > 2)
                {
                    Importer.TheLog.LogWarning(Id, "Renamed parameter: " + originalParameterName + " to: " + parameterName, false);
                }

                if (existingParameter == null)
                {
                    ForgeTypeId specTypeId;
                    ForgeTypeId unitsTypeId = null;

                    if (IFCUnit != null)
                    {
                        specTypeId  = IFCUnit.Spec;
                        unitsTypeId = IFCUnit.Unit;
                    }
                    else
                    {
                        specTypeId = IFCDataUtil.GetUnitTypeFromData(Value, SpecTypeId.Number);
                    }

                    bool created = IFCPropertySet.AddParameterDouble(doc, element, category, objDef, parameterName, specTypeId, unitsTypeId, doubleValueToUse, Id);
                    if (created)
                    {
                        createdParameters.Add(parameterName);
                    }

                    return;
                }
            }

            bool setValue = true;

            switch (existingParameter.StorageType)
            {
            case StorageType.String:
                existingParameter.Set(doubleValueToUse.ToString());
                break;

            case StorageType.Double:
                existingParameter.Set(doubleValueToUse);
                break;

            default:
                setValue = false;
                break;
            }

            if (!setValue)
            {
                Importer.TheLog.LogError(Id, "Couldn't create parameter: " + Name + " of storage type: " + existingParameter.StorageType.ToString(), false);
            }
        }
Esempio n. 9
0
        /// <summary>
        /// Creates or populates Revit elements based on the information contained in this class.
        /// </summary>
        /// <param name="doc">The document.</param>
        protected virtual void TraverseSubElements(Document doc)
        {
            IList <ElementId> subElementIds = new List <ElementId>();

            // These two should only be populated if GroupSubElements() is true and we are duplicating geometry for containers.
            List <GeometryObject> groupedSubElementGeometries      = new List <GeometryObject>();
            List <Curve>          groupedSubElementFootprintCurves = new List <Curve>();

            if (ComposedObjectDefinitions != null)
            {
                foreach (IFCObjectDefinition objectDefinition in ComposedObjectDefinitions)
                {
                    IFCObjectDefinition.CreateElement(doc, objectDefinition);
                    if (objectDefinition.CreatedElementId != ElementId.InvalidElementId)
                    {
                        subElementIds.Add(objectDefinition.CreatedElementId);

                        // CreateDuplicateContainerGeometry is currently an API-only option (no UI), set to true by default.
                        if (GroupSubElements() && Importer.TheOptions.CreateDuplicateContainerGeometry)
                        {
                            IList <GeometryObject> subGeometries = GetOrCloneGeometry(doc, objectDefinition);
                            if (subGeometries != null)
                            {
                                groupedSubElementGeometries.AddRange(subGeometries);
                            }

                            if (objectDefinition is IFCProduct)
                            {
                                groupedSubElementFootprintCurves.AddRange((objectDefinition as IFCProduct).FootprintCurves);
                            }
                        }
                    }
                }
            }

            if (GroupSubElements())
            {
                if (subElementIds.Count > 0)
                {
                    if (CreatedElementId != ElementId.InvalidElementId)
                    {
                        subElementIds.Add(CreatedElementId);
                    }

                    // We aren't yet actually grouping the elements.  DirectShape doesn't support grouping, and
                    // the Group element doesn't support adding parameters.  For now, we will create a DirectShape that "forgets"
                    // the association, which is good enough for link.
                    DirectShape directShape = IFCElementUtil.CreateElement(doc, CategoryId, GlobalId, groupedSubElementGeometries);
                    //Group group = doc.Create.NewGroup(subElementIds);

                    if (directShape != null)
                    {
                        CreatedElementId = directShape.Id;
                        CreatedGeometry  = groupedSubElementGeometries;

                        if (groupedSubElementFootprintCurves.Count != 0 && this is IFCProduct)
                        {
                            using (IFCImportShapeEditScope planViewScope = IFCImportShapeEditScope.Create(doc, this as IFCProduct))
                            {
                                planViewScope.AddPlanViewCurves(groupedSubElementFootprintCurves, Id);
                                planViewScope.SetPlanViewRep(directShape);
                            }
                        }
                    }
                    else
                    {
                        Importer.TheLog.LogCreationError(this, null, false);
                    }
                }
            }
        }
Esempio n. 10
0
      /// <summary>
      /// Create a copying of the geometry of an entity with a different graphics style.
      /// </summary>
      /// <param name="doc">The document.</param>
      /// <param name="original">The IFCProduct we are partially copying.</param>
      /// <param name="parentEntity">The IFCObjectDefinition we are going to add the geometry to.</param>
      /// <param name="cloneParentMaterial">Determine whether to use the one material of the parent entity, if it exists and is unique.</param>
      /// <returns>The list of geometries created with a new category and possibly material.</returns>
      public static IList<IFCSolidInfo> CloneElementGeometry(Document doc, IFCProduct original, IFCObjectDefinition parentEntity, bool cloneParentMaterial)
      {
         using (TemporaryDisableLogging disableLogging = new TemporaryDisableLogging())
         {
            IFCElement clone = new IFCElement();

            // Note that the GlobalId is left to null here; this allows us to later decide not to create a DirectShape for the result.

            // Get the ObjectLocation and ProductRepresentation from the original entity, which is all we need to create geometry.
            clone.ObjectLocation = original.ObjectLocation;
            clone.ProductRepresentation = original.ProductRepresentation;
            clone.MaterialSelect = original.MaterialSelect;

            // Get the EntityType and PredefinedType from the parent to ensure that it "matches" the category and graphics style of the parent.
            clone.EntityType = parentEntity.EntityType;
            clone.PredefinedType = parentEntity.PredefinedType;

            if (cloneParentMaterial)
            {
               // This will only work if the parent entity has one material.
               IFCMaterial parentMaterial = parentEntity.GetTheMaterial();
               if (parentMaterial != null)
                  clone.MaterialSelect = parentMaterial;
            }

            IList<GeometryObject> geomObjs = new List<GeometryObject>();
            CreateElement(doc, clone);
            return clone.Solids;
         }
      }
Esempio n. 11
0
        /// <summary>
        /// Create a copying of the geometry of an entity with a different graphics style.
        /// </summary>
        /// <param name="doc">The document.</param>
        /// <param name="original">The IFCProduct we are partially copying.</param>
        /// <param name="parentEntity">The IFCObjectDefinition we are going to add the geometry to.</param>
        /// <param name="cloneParentMaterial">Determine whether to use the one material of the parent entity, if it exists and is unique.</param>
        /// <returns>The list of geometries created with a new category and possibly material.</returns>
        public static IList <IFCSolidInfo> CloneElementGeometry(Document doc, IFCProduct original, IFCObjectDefinition parentEntity, bool cloneParentMaterial)
        {
            using (TemporaryDisableLogging disableLogging = new TemporaryDisableLogging())
            {
                IFCElement clone = new IFCElement();

                // Note that the GlobalId is left to null here; this allows us to later decide not to create a DirectShape for the result.

                // Get the ObjectLocation and ProductRepresentation from the original entity, which is all we need to create geometry.
                clone.ObjectLocation        = original.ObjectLocation;
                clone.ProductRepresentation = original.ProductRepresentation;
                clone.MaterialSelect        = original.MaterialSelect;

                // Get the EntityType and PredefinedType from the parent to ensure that it "matches" the category and graphics style of the parent.
                clone.EntityType     = parentEntity.EntityType;
                clone.PredefinedType = parentEntity.PredefinedType;

                if (cloneParentMaterial)
                {
                    // This will only work if the parent entity has one material.
                    IFCMaterial parentMaterial = parentEntity.GetTheMaterial();
                    if (parentMaterial != null)
                    {
                        clone.MaterialSelect = parentMaterial;
                    }
                }

                IList <GeometryObject> geomObjs = new List <GeometryObject>();
                CreateElement(doc, clone);
                return(clone.Solids);
            }
        }
 /// <summary>
 /// Get the entity type and predefined 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="typePredefinedType">The IfcTypeObject predefined type, if it exists.</param>
 private static void GetAssociatedTypeEntityInfo(IFCObjectDefinition entity, out IFCEntityType? typeEntityType, out string typePredefinedType)
 {
     typeEntityType = null;
     typePredefinedType = 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;
             typePredefinedType = typeObject.PredefinedType;
         }
     }
 }
Esempio n. 13
0
        /// <summary>
        /// Create quantities for a given element.
        /// </summary>
        /// <param name="doc">The document.</param>
        /// <param name="element">The element being created.</param>
        /// <param name="parameterGroupMap">The parameters of the element.  Cached for performance.</param>
        /// <returns>The name of the property set created, if it was created, and a Boolean value if it should be added to the property set list.</returns>
        public override Tuple <string, bool> CreatePropertySet(Document doc, Element element, IFCObjectDefinition objDef, IFCParameterSetByGroup parameterGroupMap)
        {
            Category category = IFCPropertySet.GetCategoryForParameterIfValid(element, Id);

            string quotedName = "\"" + Name + "\"";

            ISet <string> parametersCreated = new HashSet <string>();

            foreach (IFCPhysicalQuantity quantity in IFCQuantities.Values)
            {
                quantity.Create(doc, element, category, objDef, parameterGroupMap, Name, parametersCreated);
            }

            return(Tuple.Create(quotedName, true));
        }
      private IList<GeometryObject> GetOrCloneGeometry(Document doc, IFCObjectDefinition objectDefinition)
      {
         if (!(objectDefinition is IFCBuildingElementPart))
            return objectDefinition.CreatedGeometry;

         // In the case of IFCBuildingElementPart, we want the container to have a copy of the geometry in the category of the parent,
         // as otherwise the geometry will be controlled by default by the Parts category instead of the parent category.
         IList<IFCSolidInfo> clonedGeometry = IFCElement.CloneElementGeometry(doc, objectDefinition as IFCProduct, this, false);
         if (clonedGeometry == null)
            return null;

         IList<GeometryObject> geomObjs = new List<GeometryObject>();

         foreach (IFCSolidInfo solid in clonedGeometry)
         {
            geomObjs.Add(solid.GeometryObject);
         }

         return geomObjs;
      }
Esempio n. 15
0
        /// <summary>
        /// Add an int parameter to an element.
        /// </summary>
        /// <param name="doc">The document.</param>
        /// <param name="element">The element.</param>
        /// <param name="category">The category of the element.</param>
        /// <param name="parameterName">The parameter name.</param>
        /// <param name="parameterValue">The parameter value.</param>
        /// <param name="parameterSetId">The id of the containing parameter set, for reporting errors.</param>
        /// <returns>True if the parameter was successfully added, false otherwise.</returns>
        public static bool AddParameterInt(Document doc, Element element, Category category, IFCObjectDefinition objDef, string parameterName, int parameterValue, int parameterSetId)
        {
            if (doc == null || element == null || category == null)
            {
                return(false);
            }

            bool?processedParameter = Importer.TheProcessor.ProcessParameter(objDef.Id, parameterSetId, parameterName, parameterValue);

            if (processedParameter.HasValue)
            {
                return(processedParameter.Value);
            }

            Parameter parameter = AddParameterBase(doc, element, category, parameterName, parameterSetId, SpecTypeId.Int.Integer);

            if (parameter == null)
            {
                return(false);
            }

            parameter.Set(parameterValue);
            return(true);
        }
Esempio n. 16
0
        /// <summary>
        /// Adds a parameter with the name of an element represented by an ElementId to an element.
        /// </summary>
        /// <param name="doc">The document.</param>
        /// <param name="element">The element.</param>
        /// <param name="category">The category of the element.</param>
        /// <param name="parameterName">The parameter name.</param>
        /// <param name="parameterValue">The parameter value.</param>
        /// <param name="parameterSetId">The id of the containing parameter set, for reporting errors.</param>
        /// <returns>True if the parameter was successfully added, false otherwise.</returns>
        public static bool AddParameterElementId(Document doc, Element element, Category category, IFCObjectDefinition objDef, string parameterName, ElementId parameterValue, int parameterSetId)
        {
            if (doc == null || element == null || category == null)
            {
                return(false);
            }

            Element parameterElement = doc.GetElement(parameterValue);

            if (parameterElement == null)
            {
                return(false);
            }

            string name = parameterElement.Name;

            if (string.IsNullOrEmpty(name))
            {
                return(false);
            }

            bool?processedParameter = Importer.TheProcessor.ProcessParameter(objDef.Id, parameterSetId, parameterName, parameterValue);

            if (processedParameter.HasValue)
            {
                return(processedParameter.Value);
            }

            Parameter parameter = AddParameterBase(doc, element, category, parameterName, parameterSetId, SpecTypeId.String.Text);

            if (parameter == null)
            {
                return(false);
            }

            parameter.Set(name);
            return(true);
        }
 /// <summary>
 /// Create a property set for a given element.
 /// </summary>
 /// <param name="doc">The document.</param>
 /// <param name="element">The element being created.</param>
 /// <param name="parameterGroupMap">The parameters of the element.  Cached for performance.</param>
 /// <returns>The name of the property set created, if it was created, and a Boolean value if it should be added to the property set list.</returns>
 public virtual Tuple <string, bool> CreatePropertySet(Document doc, Element element, IFCObjectDefinition objDef, IFCParameterSetByGroup parameterGroupMap)
 {
     return(new Tuple <string, bool>(null, false));
 }
        /// <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 typePredefinedType = null;
            GetAssociatedTypeEntityInfo(entity, out typeEntityType, out typePredefinedType);

            // Use the IfcTypeObject predefined type if the IfcElement predefined type is either null, empty, white space, or not defined.
            string predefinedType = entity.PredefinedType;
            if ((string.IsNullOrWhiteSpace(predefinedType) || (string.Compare(predefinedType, "NOTDEFINED", true) == 0)) &&
                !string.IsNullOrWhiteSpace(typePredefinedType))
                predefinedType = typePredefinedType;

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

            ElementId catElemId = GetCategoryElementId(entityType, predefinedType);

            // 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, predefinedType);
            }

            Category subCategory = null;
            if (catElemId.IntegerValue == (int)BuiltInCategory.OST_GenericModel)
            {
                string subCategoryName = GetCustomCategoryName(entity);

                subCategory = GetOrCreateSubcategory(doc, entity.Id, subCategoryName);
                if (subCategory != null)
                {
                    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 &&
                    entityType != IFCEntityType.IfcSystem)
                {
                   string msg = "Setting IFC entity ";
                   if (string.IsNullOrWhiteSpace(predefinedType))
                      msg = entityType.ToString();
                   else
                      msg = entityType.ToString() + "." + predefinedType;

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

                   msg += " to Generic Models.";
                   Importer.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;
        }
        /// <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 predefinedType = entity.PredefinedType;

            IFCEntityType? typeEntityType = null;
            string typePredefinedType = null;
            GetAssociatedTypeEntityInfo(entity, out typeEntityType, out typePredefinedType);

            if (typeEntityType.HasValue)
                entityType = typeEntityType.Value;
            if (string.IsNullOrWhiteSpace(predefinedType) && !string.IsNullOrWhiteSpace(typePredefinedType))
                predefinedType = typePredefinedType;

            string categoryName = entityType.ToString();
            if (!string.IsNullOrWhiteSpace(predefinedType))
                categoryName += "." + predefinedType;
            return categoryName;
        }
        /// <summary>
        /// Add a string parameter to an element.
        /// </summary>
        /// <param name="doc">The document.</param>
        /// <param name="element">The element.</param>
        /// <param name="objDef">The IFCObjectDefinition that created the element.</param>
        /// <param name="name">The enum corresponding to the parameter name.</param>
        /// <param name="parameterValue">The parameter value.</param>
        /// <param name="parameterSetId">The id of the containing parameter set, for reporting errors.</param>
        /// <returns>True if the parameter was successfully added, false otherwise.</returns>
        public static bool AddParameterString(Document doc, Element element, IFCObjectDefinition objDef, IFCSharedParameters name, string parameterValue, int parameterSetId)
        {
            if (objDef == null)
                return false;

            string parameterName = objDef.GetSharedParameterName(name);

            Parameter parameter = AddParameterBase(doc, element, parameterName, parameterSetId, ParameterType.Text);
            if (parameter == null)
                return false;

            parameter.Set(parameterValue);
            return true;
        }
Esempio n. 21
0
        /// <summary>
        /// Add a string parameter to an element.
        /// </summary>
        /// <param name="doc">The document.</param>
        /// <param name="element">The element.</param>
        /// <param name="category">The category of the element.</param>
        /// <param name="objDef">The IFCObjectDefinition that created the element.</param>
        /// <param name="name">The enum corresponding to the parameter name.</param>
        /// <param name="parameterValue">The parameter value.</param>
        /// <param name="parameterSetId">The id of the containing parameter set, for reporting errors.</param>
        /// <returns>True if the parameter was successfully added, false otherwise.</returns>
        public static bool AddParameterString(Document doc, Element element, Category category, IFCObjectDefinition objDef, IFCSharedParameters name, string parameterValue, int parameterSetId)
        {
            if (doc == null || element == null || category == null || objDef == null)
            {
                return(false);
            }

            string parameterName = objDef.GetSharedParameterName(name, element is ElementType);

            bool?processedParameter = Importer.TheProcessor.ProcessParameter(objDef.Id, parameterSetId, parameterName, parameterValue);

            if (processedParameter.HasValue)
            {
                return(processedParameter.Value);
            }

            Parameter parameter = AddParameterBase(doc, element, category, parameterName, parameterSetId, SpecTypeId.String.Text);

            if (parameter == null)
            {
                return(false);
            }

            parameter.Set(parameterValue);
            return(true);
        }
        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();
        }
      /// <summary>
      /// Create one or more elements 
      /// </summary>
      /// <param name="doc">The document being populated.</param>
      /// <returns>The primary element associated with the IFCObjectDefinition, or InvalidElementId if it failed.</returns>
      public static ElementId CreateElement(Document doc, IFCObjectDefinition objDef)
      {
         // This would be a good place to check 'objDef.GlobalId'.

         ElementId createdElementId = objDef.CreatedElementId;
         try
         {
            if ((createdElementId == ElementId.InvalidElementId) && objDef.IsValidForCreation)
            {
               ElementId gstyleId;
               objDef.CategoryId = IFCCategoryUtil.GetCategoryIdForEntity(doc, objDef, out gstyleId);
               objDef.GraphicsStyleId = gstyleId;

               if (objDef is IFCObject)
               {
                  IFCObject asObject = objDef as IFCObject;
                  foreach (IFCTypeObject typeObject in asObject.TypeObjects)
                     IFCObjectDefinition.CreateElement(doc, typeObject);
               }

               objDef.Create(doc);
               objDef.CreateParameters(doc);
               createdElementId = objDef.CreatedElementId;
               Importer.TheLog.AddCreatedEntity(doc, objDef);
            }
         }
         catch (Exception ex)
         {
            if (objDef != null)
            {
               objDef.IsValidForCreation = false;
               Importer.TheLog.LogCreationError(objDef, ex.Message, false);
            }
         }
         return createdElementId;
      }
      /// <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();
         }
      }
Esempio n. 25
0
        /// <summary>
        /// Create a property for a given element.
        /// </summary>
        /// <param name="doc">The document.</param>
        /// <param name="element">The element being created.</param>
        /// <param name="category">The category of the element being created.</param>
        /// <param name="parameterMap">The parameters of the element.  Cached for performance.</param>
        /// <param name="propertySetName">The name of the containing property set.</param>
        /// <param name="createdParameters">The names of the created parameters.</param>
        public void Create(Document doc, Element element, Category category, IFCObjectDefinition objDef, IFCParameterSetByGroup parameterGroupMap, string propertySetName, ISet <string> createdParameters)
        {
            // Try to get the single value from the property.  If we can't get a single value, get it as a string.
            IFCPropertyValue propertyValueToUse = null;

            if (this is IFCSimpleProperty)
            {
                IFCSimpleProperty        simpleProperty = this as IFCSimpleProperty;
                IList <IFCPropertyValue> propertyValues = simpleProperty.IFCPropertyValues;
                if (propertyValues != null && propertyValues.Count == 1)
                {
                    // If the value isn't set, skip it.  We won't warn.
                    if (!propertyValues[0].HasValue())
                    {
                        return;
                    }

                    propertyValueToUse = propertyValues[0];
                }
            }

            IFCDataPrimitiveType dataType    = IFCDataPrimitiveType.Unknown;
            ForgeTypeId          specTypeId  = new ForgeTypeId();
            ForgeTypeId          unitsTypeId = null;

            bool?      boolValueToUse      = null;
            IFCLogical?logicalValueToUse   = null;
            int?       intValueToUse       = null;
            double?    doubleValueToUse    = null;
            ElementId  elementIdValueToUse = null;
            string     stringValueToUse    = null;

            if (propertyValueToUse == null)
            {
                string propertyValueAsString = PropertyValueAsString();
                if (propertyValueAsString == null)
                {
                    Importer.TheLog.LogError(Id, "Couldn't create parameter: " + Name, false);
                    return;
                }

                dataType         = IFCDataPrimitiveType.String;
                stringValueToUse = propertyValueAsString;
            }
            else
            {
                dataType = propertyValueToUse.Value.PrimitiveType;
                if (dataType == IFCDataPrimitiveType.Instance)
                {
                    IFCAnyHandle propertyValueHandle = propertyValueToUse.Value.AsInstance();
                    ElementId    propertyValueAsId   = IFCObjectReferenceSelect.ToElementId(propertyValueHandle);
                    if (propertyValueAsId != ElementId.InvalidElementId)
                    {
                        elementIdValueToUse = propertyValueAsId;
                    }
                    else
                    {
                        stringValueToUse = IFCObjectReferenceSelect.ToString(propertyValueHandle);
                        dataType         = IFCDataPrimitiveType.String;
                    }
                }
                else
                {
                    switch (dataType)
                    {
                    case IFCDataPrimitiveType.String:
                    case IFCDataPrimitiveType.Enumeration:
                    case IFCDataPrimitiveType.Binary:
                        stringValueToUse = propertyValueToUse.AsString();
                        break;

                    case IFCDataPrimitiveType.Integer:
                        intValueToUse = propertyValueToUse.AsInteger();
                        break;

                    case IFCDataPrimitiveType.Boolean:
                        boolValueToUse = propertyValueToUse.AsBoolean();
                        break;

                    case IFCDataPrimitiveType.Logical:
                        logicalValueToUse = propertyValueToUse.AsLogical();
                        break;

                    case IFCDataPrimitiveType.Double:
                        if (propertyValueToUse.IFCUnit != null)
                        {
                            specTypeId  = propertyValueToUse.IFCUnit.Spec;
                            unitsTypeId = propertyValueToUse.IFCUnit.Unit;
                        }
                        else
                        {
                            specTypeId = IFCDataUtil.GetUnitTypeFromData(propertyValueToUse.Value, SpecTypeId.Number);
                        }

                        doubleValueToUse = Importer.TheProcessor.ScaleValues ?
                                           propertyValueToUse.AsScaledDouble() :
                                           propertyValueToUse.AsUnscaledDouble();
                        break;

                    default:
                        Importer.TheLog.LogError(Id, "Unknown value type for parameter: " + Name, false);
                        return;
                    }
                }
            }

            if (stringValueToUse != null && stringValueToUse.Length == 0)
            {
                return;
            }

            Parameter existingParameter     = null;
            bool      elementIsType         = (element is ElementType);
            string    typeString            = elementIsType ? " " + Resources.IFCTypeSchedule : string.Empty;
            string    originalParameterName = propertySetName + "." + Name + typeString;
            string    parameterName         = originalParameterName;

            if (parameterGroupMap.TryFindParameter(parameterName, out existingParameter))
            {
                if ((existingParameter != null) && !IsValidParameterType(existingParameter, dataType))
                {
                    existingParameter = null;
                }
            }

            if (existingParameter == null)
            {
                int parameterNameCount = 2;
                while (createdParameters.Contains(parameterName))
                {
                    parameterName = originalParameterName + " " + parameterNameCount;
                    parameterNameCount++;
                }
                if (parameterNameCount > 2)
                {
                    Importer.TheLog.LogWarning(Id, "Renamed parameter: " + originalParameterName + " to: " + parameterName, false);
                }

                bool created = false;
                switch (dataType)
                {
                case IFCDataPrimitiveType.String:
                case IFCDataPrimitiveType.Enumeration:
                case IFCDataPrimitiveType.Binary:
                    created = IFCPropertySet.AddParameterString(doc, element, category, objDef, parameterName, stringValueToUse, Id);
                    break;

                case IFCDataPrimitiveType.Integer:
                    created = IFCPropertySet.AddParameterInt(doc, element, category, objDef, parameterName, intValueToUse.Value, Id);
                    break;

                case IFCDataPrimitiveType.Boolean:
                    created = IFCPropertySet.AddParameterBoolean(doc, element, category, objDef, parameterName, boolValueToUse.Value, Id);
                    break;

                case IFCDataPrimitiveType.Logical:
                    if (logicalValueToUse != IFCLogical.Unknown)
                    {
                        created = IFCPropertySet.AddParameterBoolean(doc, element, category, objDef, parameterName, (logicalValueToUse == IFCLogical.True), Id);
                    }
                    break;

                case IFCDataPrimitiveType.Double:
                    created = IFCPropertySet.AddParameterDouble(doc, element, category, objDef, parameterName, specTypeId, unitsTypeId, doubleValueToUse.Value, Id);
                    break;

                case IFCDataPrimitiveType.Instance:
                    created = IFCPropertySet.AddParameterElementId(doc, element, category, objDef, parameterName, elementIdValueToUse, Id);
                    break;
                }

                if (created)
                {
                    createdParameters.Add(originalParameterName);
                }

                return;
            }

            bool couldSetValue = false;

            switch (existingParameter.StorageType)
            {
            case StorageType.String:
            {
                switch (dataType)
                {
                case IFCDataPrimitiveType.String:
                case IFCDataPrimitiveType.Enumeration:
                case IFCDataPrimitiveType.Binary:
                    couldSetValue = existingParameter.Set(stringValueToUse);
                    break;

                case IFCDataPrimitiveType.Integer:
                    couldSetValue = existingParameter.Set(intValueToUse.Value.ToString());
                    break;

                case IFCDataPrimitiveType.Boolean:
                    couldSetValue = existingParameter.Set(boolValueToUse.Value ? "True" : "False");
                    break;

                case IFCDataPrimitiveType.Logical:
                    couldSetValue = existingParameter.Set(logicalValueToUse.ToString());
                    break;

                case IFCDataPrimitiveType.Double:
                    couldSetValue = existingParameter.Set(doubleValueToUse.ToString());
                    break;

                default:
                    break;
                }
            }
            break;

            case StorageType.Integer:
                if (dataType == IFCDataPrimitiveType.Integer)
                {
                    couldSetValue = existingParameter.Set(intValueToUse.Value);
                }
                else if (dataType == IFCDataPrimitiveType.Boolean)
                {
                    couldSetValue = existingParameter.Set(boolValueToUse.Value ? 1 : 0);
                }
                else if (dataType == IFCDataPrimitiveType.Logical)
                {
                    couldSetValue = (logicalValueToUse == IFCLogical.Unknown) ? true : existingParameter.Set((logicalValueToUse == IFCLogical.True) ? 1 : 0);
                }
                break;

            case StorageType.Double:
                if (dataType == IFCDataPrimitiveType.Double)
                {
                    couldSetValue = existingParameter.Set(doubleValueToUse.Value);
                }
                else if (dataType == IFCDataPrimitiveType.Integer)
                {
                    couldSetValue = existingParameter.Set(intValueToUse.Value);
                }
                else if (dataType == IFCDataPrimitiveType.Boolean)
                {
                    couldSetValue = existingParameter.Set(boolValueToUse.Value ? 1 : 0);
                }
                else if ((dataType == IFCDataPrimitiveType.Logical) && (logicalValueToUse != IFCLogical.Unknown))
                {
                    couldSetValue = existingParameter.Set((logicalValueToUse == IFCLogical.True) ? 1 : 0);
                }
                break;
            }

            if (!couldSetValue)
            {
                Importer.TheLog.LogError(Id, "Couldn't create parameter: " + Name + " of storage type: " + existingParameter.StorageType.ToString(), false);
            }
        }
Esempio n. 26
0
 /// <summary>
 /// Create a quantity for a given element.
 /// </summary>
 /// <param name="doc">The document.</param>
 /// <param name="element">The element being created.</param>
 /// <param name="category">The element's category.</param>
 /// <param name="parameterMap">The parameters of the element.  Cached for performance.</param>
 /// <param name="propertySetName">The name of the containing property set.</param>
 /// <param name="createdParameters">The names of the created parameters.</param>
 public abstract void Create(Document doc, Element element, Category category, IFCObjectDefinition objDef, IFCParameterSetByGroup parameterGroupMap, string propertySetName, ISet <string> createdParameters);