示例#1
0
        public MaterialConstituentCache()
        {
            MaterialConsituentInfoComparer comparer = new MaterialConsituentInfoComparer();

            if (m_MaterialConstDictionary == null)
            {
                m_MaterialConstDictionary = new Dictionary <MaterialConstituentInfo, IFCAnyHandle>(comparer);
            }
        }
示例#2
0
        /// <summary>
        /// Creates an association between a list of material handles and an instance handle, and create the relevant IfcShapeAspect
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="element">The element</param>
        /// <param name="instanceHandle">The IFC instance handle.</param>
        /// <param name="representationItemInfoSet">RepresentationItem info set</param>
        public static void CreateMaterialAssociationWithShapeAspect(ExporterIFC exporterIFC, Element element, IFCAnyHandle instanceHandle, HashSet <Tuple <MaterialConstituentInfo, IFCAnyHandle> > representationItemInfoSet)
        {
            Document document = ExporterCacheManager.Document;

            // Create material association if any.
            bool createConstituentSet      = (!ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4);
            IList <IFCAnyHandle> materials = createConstituentSet ? null : new List <IFCAnyHandle>();
            ISet <ElementId>     alreadySeenMaterialIds = createConstituentSet ? new HashSet <ElementId>() : null;
            IFCAnyHandle         matHnd = null;

            foreach (Tuple <MaterialConstituentInfo, IFCAnyHandle> repItemInfo in representationItemInfoSet)
            {
                matHnd = GetOrCreateMaterialHandle(exporterIFC, repItemInfo.Item1.MaterialId);
                if (IFCAnyHandleUtil.IsNullOrHasNoValue(matHnd))
                {
                    continue;
                }

                // Strictly speaking, we only need at most one material if createConstituentSet is true.
                if (createConstituentSet)
                {
                    alreadySeenMaterialIds.Add(repItemInfo.Item1.MaterialId);
                }
                else
                {
                    materials.Add(matHnd);
                }
            }

            int numMaterials = createConstituentSet ? alreadySeenMaterialIds.Count : materials.Count;

            if (numMaterials == 0)
            {
                return;
            }

            // If there is only one material, we will associate the one material directly.
            // matHnd above is guaranteed to have a valid value if numMaterials > 0.
            if (numMaterials == 1)
            {
                ExporterCacheManager.MaterialRelationsCache.Add(matHnd, instanceHandle);
                return;
            }

            IFCFile      file = exporterIFC.GetFile();
            IFCAnyHandle materialContainerHnd = null;

            if (createConstituentSet)
            {
                ExporterCacheManager.MaterialConstituentCache.Reset();
                IDictionary <IFCAnyHandle, IFCAnyHandle> mapRepItemToItemDict = new Dictionary <IFCAnyHandle, IFCAnyHandle>();
                string       repType = null;
                IFCAnyHandle prodRep = null;
                if (IFCAnyHandleUtil.IsSubTypeOf(instanceHandle, IFCEntityType.IfcProduct))
                {
                    prodRep = IFCAnyHandleUtil.GetRepresentation(instanceHandle);
                    IList <IFCAnyHandle> reps = IFCAnyHandleUtil.GetRepresentations(prodRep);
                    // Get RepresentationType for shapeAspect in "Body" representation
                    foreach (IFCAnyHandle rep in reps)
                    {
                        if (IFCAnyHandleUtil.GetRepresentationIdentifier(rep).Equals("Body"))
                        {
                            repType = IFCAnyHandleUtil.GetRepresentationType(rep);
                            if (repType.Equals("MappedRepresentation", StringComparison.InvariantCultureIgnoreCase))
                            {
                                HashSet <IFCAnyHandle> items = IFCAnyHandleUtil.GetItems(rep);
                                foreach (IFCAnyHandle item in items)
                                {
                                    IFCAnyHandle mappingSource    = IFCAnyHandleUtil.GetInstanceAttribute(item, "MappingSource");
                                    IFCAnyHandle mappingSourceRep = IFCAnyHandleUtil.GetInstanceAttribute(mappingSource, "MappedRepresentation");
                                    repType = IFCAnyHandleUtil.GetRepresentationType(mappingSourceRep);
                                }
                            }
                            break;
                        }
                    }
                }
                else if (IFCAnyHandleUtil.IsSubTypeOf(instanceHandle, IFCEntityType.IfcTypeProduct))
                {
                    IList <IFCAnyHandle> repMaps = IFCAnyHandleUtil.GetAggregateInstanceAttribute <List <IFCAnyHandle> >(instanceHandle, "RepresentationMaps");
                    if (repMaps != null && repMaps.Count > 0)
                    {
                        // Will use representation maps for shapeAspect if there is "Body"
                        foreach (IFCAnyHandle repMap in repMaps)
                        {
                            IFCAnyHandle rep = IFCAnyHandleUtil.GetInstanceAttribute(repMap, "MappedRepresentation");
                            if (IFCAnyHandleUtil.GetRepresentationIdentifier(rep).Equals("Body"))
                            {
                                prodRep = repMap;
                                repType = IFCAnyHandleUtil.GetRepresentationType(rep);
                                break;
                            }
                        }
                    }
                }

                // Collect ALL representationItems that have the same Category and MaterialId into one Set
                MaterialConsituentInfoComparer comparer = new MaterialConsituentInfoComparer();
                IDictionary <MaterialConstituentInfo, HashSet <IFCAnyHandle> > repItemInfoGroup = new Dictionary <MaterialConstituentInfo, HashSet <IFCAnyHandle> >(comparer);
                foreach (Tuple <MaterialConstituentInfo, IFCAnyHandle> repItemInfo in representationItemInfoSet)
                {
                    if (!repItemInfoGroup.ContainsKey(repItemInfo.Item1))
                    {
                        HashSet <IFCAnyHandle> repItemSet = new HashSet <IFCAnyHandle>()
                        {
                            repItemInfo.Item2
                        };
                        repItemInfoGroup.Add(repItemInfo.Item1, repItemSet);
                    }
                    else
                    {
                        repItemInfoGroup[repItemInfo.Item1].Add(repItemInfo.Item2);
                    }
                }

                HashSet <IFCAnyHandle> constituentSet = new HashSet <IFCAnyHandle>();
                // in IFC4 we will create IfcConstituentSet instead of MaterialList, create the associated IfcConstituent here from IfcMaterial
                foreach (KeyValuePair <MaterialConstituentInfo, HashSet <IFCAnyHandle> > repItemInfoSet in repItemInfoGroup)
                {
                    IFCAnyHandle constituentHnd = GetOrCreateMaterialConstituent(exporterIFC, repItemInfoSet.Key);
                    if (!IFCAnyHandleUtil.IsNullOrHasNoValue(constituentHnd))
                    {
                        constituentSet.Add(constituentHnd);
                    }

                    RepresentationUtil.CreateRepForShapeAspect(exporterIFC, element, prodRep, repType, repItemInfoSet.Key.ComponentCat, repItemInfoSet.Value);
                }

                if (constituentSet.Count > 0)
                {
                    materialContainerHnd = GetOrCreateMaterialConstituentSet(file, instanceHandle, constituentSet);
                    ExporterCacheManager.MaterialRelationsCache.Add(materialContainerHnd, instanceHandle);
                }
            }
            else
            {
                materialContainerHnd = CreateMaterialList(file, materials);
                ExporterCacheManager.MaterialSetUsageCache.Add(materialContainerHnd, instanceHandle);
            }
        }