예제 #1
0
        /// <summary>
        /// Creates openings if there is necessary.
        /// </summary>
        /// <param name="elementHandle">The element handle to create openings.</param>
        /// <param name="element">The element to create openings.</param>
        /// <param name="info">The extrusion data.</param>
        /// <param name="extraParams">The extrusion creation data.</param>
        /// <param name="offsetTransform">The offset transform from ExportBody, or the identity transform.</param>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="originalPlacement">The original placement handle.</param>
        /// <param name="setter">The PlacementSetter.</param>
        /// <param name="wrapper">The ProductWrapper.</param>
        private static void CreateOpeningsIfNecessaryBase(IFCAnyHandle elementHandle, Element element, IList <IFCExtrusionData> info,
                                                          IFCExtrusionCreationData extraParams, Transform offsetTransform, ExporterIFC exporterIFC,
                                                          IFCAnyHandle originalPlacement, PlacementSetter setter, ProductWrapper wrapper)
        {
            if (IFCAnyHandleUtil.IsNullOrHasNoValue(elementHandle))
            {
                return;
            }

            int sz = info.Count;

            if (sz == 0)
            {
                return;
            }

            using (TransformSetter transformSetter = TransformSetter.Create())
            {
                if (offsetTransform != null)
                {
                    transformSetter.Initialize(exporterIFC, offsetTransform.Inverse);
                }

                IFCFile   file       = exporterIFC.GetFile();
                ElementId categoryId = CategoryUtil.GetSafeCategoryId(element);
                Document  document   = element.Document;

                string openingObjectType = "Opening";

                int openingNumber = 1;
                for (int curr = info.Count - 1; curr >= 0; curr--)
                {
                    IFCAnyHandle extrusionHandle = ExtrusionExporter.CreateExtrudedSolidFromExtrusionData(exporterIFC, element, info[curr]);
                    if (IFCAnyHandleUtil.IsNullOrHasNoValue(extrusionHandle))
                    {
                        continue;
                    }

                    IFCAnyHandle styledItemHnd = BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, document,
                                                                                           extrusionHandle, ElementId.InvalidElementId);

                    HashSet <IFCAnyHandle> bodyItems = new HashSet <IFCAnyHandle>();
                    bodyItems.Add(extrusionHandle);

                    IFCAnyHandle         contextOfItems  = exporterIFC.Get3DContextHandle("Body");
                    IFCAnyHandle         bodyRep         = RepresentationUtil.CreateSweptSolidRep(exporterIFC, element, categoryId, contextOfItems, bodyItems, null);
                    IList <IFCAnyHandle> representations = new List <IFCAnyHandle>();
                    representations.Add(bodyRep);

                    IFCAnyHandle openingRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, representations);

                    IFCAnyHandle openingPlacement = ExporterUtil.CopyLocalPlacement(file, originalPlacement);
                    string       guid             = GUIDUtil.CreateGUID();
                    IFCAnyHandle ownerHistory     = exporterIFC.GetOwnerHistoryHandle();
                    string       openingName      = NamingUtil.GetIFCNamePlusIndex(element, openingNumber++);
                    string       elementId        = NamingUtil.CreateIFCElementId(element);
                    IFCAnyHandle openingElement   = IFCInstanceExporter.CreateOpeningElement(file, guid, ownerHistory,
                                                                                             openingName, null, openingObjectType, openingPlacement, openingRep, elementId);
                    wrapper.AddElement(null, openingElement, setter, extraParams, true);
                    if (ExporterCacheManager.ExportOptionsCache.ExportBaseQuantities && (extraParams != null))
                    {
                        PropertyUtil.CreateOpeningQuantities(exporterIFC, openingElement, extraParams);
                    }

                    string voidGuid = GUIDUtil.CreateGUID();
                    IFCInstanceExporter.CreateRelVoidsElement(file, voidGuid, ownerHistory, null, null, elementHandle, openingElement);
                }
            }
        }
예제 #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);
            }
        }
예제 #3
0
        /// <summary>
        /// Creates an opening from extrusion data.
        /// </summary>
        /// <param name="exporterIFC">The exporter.</param>
        /// <param name="hostObjHnd">The host handle.</param>
        /// <param name="hostPlacement">The host placement.</param>
        /// <param name="hostElement">The host element.</param>
        /// <param name="insertElement">The opening element.</param>
        /// <param name="openingGUID">The opening GUID.</param>
        /// <param name="extrusionData">The extrusion data.</param>
        /// <param name="plane">The plane.</param>
        /// <param name="isRecess">True if it is a recess.</param>
        /// <returns>The opening handle.</returns>
        static public IFCAnyHandle CreateOpening(ExporterIFC exporterIFC, IFCAnyHandle hostObjHnd, IFCAnyHandle hostPlacement, Element hostElement,
                                                 Element insertElement, string openingGUID, IFCExtrusionData extrusionData, Plane plane, bool isRecess,
                                                 PlacementSetter setter, ProductWrapper localWrapper)
        {
            IFCFile file = exporterIFC.GetFile();

            IList <CurveLoop> curveLoops = extrusionData.GetLoops();

            if (curveLoops.Count == 0)
            {
                return(null);
            }

            if (plane == null)
            {
                // assumption: first curve loop defines the plane.
                if (!curveLoops[0].HasPlane())
                {
                    return(null);
                }
                plane = curveLoops[0].GetPlane();
            }

            ElementId catId = CategoryUtil.GetSafeCategoryId(insertElement);

            IFCAnyHandle openingProdRepHnd = RepresentationUtil.CreateExtrudedProductDefShape(exporterIFC, insertElement, catId,
                                                                                              curveLoops, plane, extrusionData.ExtrusionDirection, extrusionData.ScaledExtrusionLength);

            string       openingObjectType = isRecess ? "Recess" : "Opening";
            IFCAnyHandle ownerHistory      = exporterIFC.GetOwnerHistoryHandle();
            string       openingName       = NamingUtil.GetNameOverride(insertElement, null);

            if (string.IsNullOrEmpty(openingName))
            {
                openingName = NamingUtil.GetNameOverride(hostElement, NamingUtil.CreateIFCObjectName(exporterIFC, hostElement));
            }
            IFCAnyHandle openingHnd = IFCInstanceExporter.CreateOpeningElement(file, openingGUID, ownerHistory, openingName, null,
                                                                               openingObjectType, ExporterUtil.CreateLocalPlacement(file, hostPlacement, null), openingProdRepHnd, null);
            IFCExtrusionCreationData ecData = null;

            if (ExporterCacheManager.ExportOptionsCache.ExportBaseQuantities)
            {
                double height, width;
                ecData = new IFCExtrusionCreationData();
                if (GeometryUtil.ComputeHeightWidthOfCurveLoop(curveLoops[0], plane, out height, out width))
                {
                    ecData.ScaledHeight = UnitUtil.ScaleLength(height);
                    ecData.ScaledWidth  = UnitUtil.ScaleLength(width);
                }
                else
                {
                    double area = ExporterIFCUtils.ComputeAreaOfCurveLoops(curveLoops);
                    ecData.ScaledArea = UnitUtil.ScaleArea(area);
                }
                PropertyUtil.CreateOpeningQuantities(exporterIFC, openingHnd, ecData);
            }

            if (localWrapper != null)
            {
                Element elementForProperties = null;
                if (GUIDUtil.IsGUIDFor(insertElement, openingGUID))
                {
                    elementForProperties = insertElement;
                }

                localWrapper.AddElement(elementForProperties, openingHnd, setter, ecData, true);
            }

            string voidGuid = GUIDUtil.CreateGUID();

            IFCInstanceExporter.CreateRelVoidsElement(file, voidGuid, ownerHistory, null, null, hostObjHnd, openingHnd);
            return(openingHnd);
        }
예제 #4
0
        /// <summary>
        /// Creates openings if there is necessary.
        /// </summary>
        /// <param name="elementHandle">The element handle to create openings.</param>
        /// <param name="element">The element to create openings.</param>
        /// <param name="info">The extrusion data.</param>
        /// <param name="extraParams">The extrusion creation data.</param>
        /// <param name="offsetTransform">The offset transform from ExportBody, or the identity transform.</param>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="originalPlacement">The original placement handle.</param>
        /// <param name="setter">The PlacementSetter.</param>
        /// <param name="wrapper">The ProductWrapper.</param>
        private static void CreateOpeningsIfNecessaryBase(IFCAnyHandle elementHandle, Element element, IList <IFCExtrusionData> info,
                                                          IFCExtrusionCreationData extraParams, Transform offsetTransform, ExporterIFC exporterIFC,
                                                          IFCAnyHandle originalPlacement, PlacementSetter setter, ProductWrapper wrapper)
        {
            if (IFCAnyHandleUtil.IsNullOrHasNoValue(elementHandle))
            {
                return;
            }

            int sz = info.Count;

            if (sz == 0)
            {
                return;
            }

            using (TransformSetter transformSetter = TransformSetter.Create())
            {
                if (offsetTransform != null)
                {
                    transformSetter.Initialize(exporterIFC, offsetTransform.Inverse);
                }

                IFCFile   file       = exporterIFC.GetFile();
                ElementId categoryId = CategoryUtil.GetSafeCategoryId(element);

                string openingObjectType = "Opening";

                int openingNumber = 1;
                for (int curr = info.Count - 1; curr >= 0; curr--)
                {
                    IFCAnyHandle extrusionHandle =
                        ExtrusionExporter.CreateExtrudedSolidFromExtrusionData(exporterIFC, element,
                                                                               info[curr], out _);
                    if (IFCAnyHandleUtil.IsNullOrHasNoValue(extrusionHandle))
                    {
                        continue;
                    }

                    // Openings shouldn't have surface styles for their geometry.
                    HashSet <IFCAnyHandle> bodyItems = new HashSet <IFCAnyHandle>()
                    {
                        extrusionHandle
                    };

                    IFCAnyHandle representationHnd = RepresentationUtil.CreateSweptSolidRep(exporterIFC,
                                                                                            element, categoryId, exporterIFC.Get3DContextHandle("Body"), bodyItems, null);
                    IList <IFCAnyHandle> representations = IFCAnyHandleUtil.IsNullOrHasNoValue(representationHnd) ?
                                                           null : new List <IFCAnyHandle>()
                    {
                        representationHnd
                    };

                    IFCAnyHandle openingRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null,
                                                                                               null, representations);

                    IFCAnyHandle openingPlacement = ExporterUtil.CopyLocalPlacement(file, originalPlacement);
                    string       guid             = GUIDUtil.GenerateIFCGuidFrom(IFCEntityType.IfcOpeningElement,
                                                                                 openingNumber.ToString(), elementHandle);
                    IFCAnyHandle ownerHistory       = ExporterCacheManager.OwnerHistoryHandle;
                    string       openingName        = NamingUtil.GetIFCNamePlusIndex(element, openingNumber++);
                    string       openingDescription = NamingUtil.GetDescriptionOverride(element, null);
                    string       openingTag         = NamingUtil.GetTagOverride(element);

                    IFCAnyHandle openingElement = IFCInstanceExporter.CreateOpeningElement(exporterIFC,
                                                                                           guid, ownerHistory, openingName, openingDescription, openingObjectType,
                                                                                           openingPlacement, openingRep, openingTag);
                    IFCExportInfoPair exportInfo = new IFCExportInfoPair(IFCEntityType.IfcOpeningElement);
                    wrapper.AddElement(null, openingElement, setter, extraParams, true, exportInfo);

                    if (ExporterCacheManager.ExportOptionsCache.ExportBaseQuantities && (extraParams != null))
                    {
                        PropertyUtil.CreateOpeningQuantities(exporterIFC, openingElement, extraParams);
                    }

                    string voidGuid = GUIDUtil.GenerateIFCGuidFrom(IFCEntityType.IfcRelVoidsElement,
                                                                   elementHandle, openingElement);
                    IFCInstanceExporter.CreateRelVoidsElement(file, voidGuid, ownerHistory, null, null,
                                                              elementHandle, openingElement);
                }
            }
        }