Esempio n. 1
0
        /// <summary>
        /// Gets the material Id of the first layer of the host object.
        /// </summary>
        /// <param name="hostObject">The host object.</param>
        /// <returns>The material id.</returns>
        public static ElementId GetFirstLayerMaterialId(HostObject hostObject)
        {
            ElementId         typeElemId  = hostObject.GetTypeId();
            HostObjAttributes hostObjAttr = hostObject.Document.GetElement(typeElemId) as HostObjAttributes;

            if (hostObjAttr == null)
            {
                return(ElementId.InvalidElementId);
            }

            CompoundStructure cs = hostObjAttr.GetCompoundStructure();

            if (cs != null)
            {
                ElementId matId = cs.LayerCount > 0 ? cs.GetMaterialId(0) : ElementId.InvalidElementId;
                if (matId != ElementId.InvalidElementId)
                {
                    return(matId);
                }
                else
                {
                    return(CategoryUtil.GetBaseMaterialIdForElement(hostObject));
                };
            }

            return(ElementId.InvalidElementId);
        }
Esempio n. 2
0
        /// <summary>
        /// Gets the material ids of finish function of the host object.
        /// </summary>
        /// <param name="hostObject">The host object.</param>
        /// <returns>The material ids.</returns>
        public static ISet <ElementId> GetFinishMaterialIds(HostObject hostObject)
        {
            HashSet <ElementId> matIds = new HashSet <ElementId>();

            ElementId         typeElemId  = hostObject.GetTypeId();
            HostObjAttributes hostObjAttr = hostObject.Document.GetElement(typeElemId) as HostObjAttributes;

            if (hostObjAttr == null)
            {
                return(matIds);
            }

            ElementId         baseMatId = CategoryUtil.GetBaseMaterialIdForElement(hostObject);
            CompoundStructure cs        = hostObjAttr.GetCompoundStructure();

            if (cs != null)
            {
                for (int i = 0; i < cs.LayerCount; ++i)
                {
                    MaterialFunctionAssignment function = cs.GetLayerFunction(i);
                    if (function == MaterialFunctionAssignment.Finish1 || function == MaterialFunctionAssignment.Finish2)
                    {
                        ElementId matId = cs.GetMaterialId(i);
                        if (matId != ElementId.InvalidElementId)
                        {
                            matIds.Add(matId);
                        }
                        else if (baseMatId != ElementId.InvalidElementId)
                        {
                            matIds.Add(baseMatId);
                        }
                    }
                }
            }

            return(matIds);
        }
Esempio n. 3
0
        /// <summary>
        /// Exports materials for host object.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="hostObject">The host object.</param>
        /// <param name="elemHnds">The host IFC handles.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        /// <param name="levelId">The level id.</param>
        /// <param name="direction">The IFCLayerSetDirection.</param>
        /// <param name="containsBRepGeometry">True if the geometry contains BRep geoemtry.  If so, we will export an IfcMaterialList</param>
        /// <returns>True if exported successfully, false otherwise.</returns>
        public static bool ExportHostObjectMaterials(ExporterIFC exporterIFC, HostObject hostObject,
                                                     IList <IFCAnyHandle> elemHnds, GeometryElement geometryElement, ProductWrapper productWrapper,
                                                     ElementId levelId, Toolkit.IFCLayerSetDirection direction, bool containsBRepGeometry)
        {
            if (hostObject == null)
            {
                return(true); //nothing to do
            }
            if (elemHnds == null || (elemHnds.Count == 0))
            {
                return(true); //nothing to do
            }
            IFCFile file = exporterIFC.GetFile();

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                if (productWrapper != null)
                {
                    productWrapper.ClearFinishMaterials();
                }

                double scaledOffset = 0.0, scaledWallWidth = 0.0, wallHeight = 0.0;
                Wall   wall = hostObject as Wall;
                if (wall != null)
                {
                    scaledWallWidth = UnitUtil.ScaleLength(wall.Width);
                    scaledOffset    = -scaledWallWidth / 2.0;
                    BoundingBoxXYZ boundingBox = wall.get_BoundingBox(null);
                    if (boundingBox != null)
                    {
                        wallHeight = boundingBox.Max.Z - boundingBox.Min.Z;
                    }
                }

                ElementId    typeElemId       = hostObject.GetTypeId();
                IFCAnyHandle materialLayerSet = ExporterCacheManager.MaterialLayerSetCache.Find(typeElemId);
                // Roofs with no components are only allowed one material.  We will arbitrarily choose the thickest material.
                IFCAnyHandle primaryMaterialHnd = ExporterCacheManager.MaterialLayerSetCache.FindPrimaryMaterialHnd(typeElemId);
                if (IFCAnyHandleUtil.IsNullOrHasNoValue(materialLayerSet))
                {
                    HostObjAttributes hostObjAttr = hostObject.Document.GetElement(typeElemId) as HostObjAttributes;
                    if (hostObjAttr == null)
                    {
                        return(true); //nothing to do
                    }
                    List <ElementId> matIds = new List <ElementId>();
                    List <double>    widths = new List <double>();
                    List <MaterialFunctionAssignment> functions = new List <MaterialFunctionAssignment>();
                    ElementId         baseMatId = CategoryUtil.GetBaseMaterialIdForElement(hostObject);
                    CompoundStructure cs        = hostObjAttr.GetCompoundStructure();
                    if (cs != null)
                    {
                        //TODO: Vertically compound structures are not yet supported by export.
                        if (!cs.IsVerticallyHomogeneous() && !MathUtil.IsAlmostZero(wallHeight))
                        {
                            cs = cs.GetSimpleCompoundStructure(wallHeight, wallHeight / 2.0);
                        }

                        for (int i = 0; i < cs.LayerCount; ++i)
                        {
                            ElementId matId = cs.GetMaterialId(i);
                            if (matId != ElementId.InvalidElementId)
                            {
                                matIds.Add(matId);
                            }
                            else
                            {
                                matIds.Add(baseMatId);
                            }
                            widths.Add(cs.GetLayerWidth(i));
                            // save layer function into ProductWrapper,
                            // it's used while exporting "Function" of Pset_CoveringCommon
                            functions.Add(cs.GetLayerFunction(i));
                        }
                    }

                    if (matIds.Count == 0)
                    {
                        matIds.Add(baseMatId);
                        widths.Add(cs != null ? cs.GetWidth() : 0);
                        functions.Add(MaterialFunctionAssignment.None);
                    }

                    // We can't create IfcMaterialLayers without creating an IfcMaterialLayerSet.  So we will simply collate here.
                    IList <IFCAnyHandle> materialHnds = new List <IFCAnyHandle>();
                    IList <int>          widthIndices = new List <int>();
                    double thickestLayer = 0.0;
                    for (int ii = 0; ii < matIds.Count; ++ii)
                    {
                        // Require positive width for IFC2x3 and before, and non-negative width for IFC4.
                        if (widths[ii] < -MathUtil.Eps())
                        {
                            continue;
                        }

                        bool almostZeroWidth = MathUtil.IsAlmostZero(widths[ii]);
                        if (ExporterCacheManager.ExportOptionsCache.FileVersion != IFCVersion.IFC4 && almostZeroWidth)
                        {
                            continue;
                        }

                        if (almostZeroWidth)
                        {
                            widths[ii] = 0.0;
                        }

                        IFCAnyHandle materialHnd = CategoryUtil.GetOrCreateMaterialHandle(exporterIFC, matIds[ii]);
                        if (primaryMaterialHnd == null || (widths[ii] > thickestLayer))
                        {
                            primaryMaterialHnd = materialHnd;
                            thickestLayer      = widths[ii];
                        }

                        widthIndices.Add(ii);
                        materialHnds.Add(materialHnd);

                        if ((productWrapper != null) && (functions[ii] == MaterialFunctionAssignment.Finish1 || functions[ii] == MaterialFunctionAssignment.Finish2))
                        {
                            productWrapper.AddFinishMaterial(materialHnd);
                        }
                    }

                    int numLayersToCreate = widthIndices.Count;
                    if (numLayersToCreate == 0)
                    {
                        return(false);
                    }

                    if (!containsBRepGeometry)
                    {
                        IList <IFCAnyHandle> layers = new List <IFCAnyHandle>(numLayersToCreate);

                        for (int ii = 0; ii < numLayersToCreate; ii++)
                        {
                            int          widthIndex    = widthIndices[ii];
                            double       scaledWidth   = UnitUtil.ScaleLength(widths[widthIndex]);
                            IFCAnyHandle materialLayer = IFCInstanceExporter.CreateMaterialLayer(file, materialHnds[ii], scaledWidth, null);
                            layers.Add(materialLayer);
                        }

                        string layerSetName = exporterIFC.GetFamilyName();
                        materialLayerSet = IFCInstanceExporter.CreateMaterialLayerSet(file, layers, layerSetName);

                        ExporterCacheManager.MaterialLayerSetCache.Register(typeElemId, materialLayerSet);
                        ExporterCacheManager.MaterialLayerSetCache.RegisterPrimaryMaterialHnd(typeElemId, primaryMaterialHnd);
                    }
                    else
                    {
                        foreach (IFCAnyHandle elemHnd in elemHnds)
                        {
                            CategoryUtil.CreateMaterialAssociations(exporterIFC, elemHnd, matIds);
                        }
                    }
                }

                // IfcMaterialLayerSetUsage is not supported for IfcWall, only IfcWallStandardCase.
                IFCAnyHandle layerSetUsage = null;
                for (int ii = 0; ii < elemHnds.Count; ii++)
                {
                    IFCAnyHandle elemHnd = elemHnds[ii];
                    if (IFCAnyHandleUtil.IsNullOrHasNoValue(elemHnd))
                    {
                        continue;
                    }

                    SpaceBoundingElementUtil.RegisterSpaceBoundingElementHandle(exporterIFC, elemHnd, hostObject.Id, levelId);
                    if (containsBRepGeometry)
                    {
                        continue;
                    }

                    HashSet <IFCAnyHandle> relDecomposesSet = IFCAnyHandleUtil.GetRelDecomposes(elemHnd);

                    IList <IFCAnyHandle> subElemHnds = null;
                    if (relDecomposesSet != null && relDecomposesSet.Count == 1)
                    {
                        IFCAnyHandle relAggregates = relDecomposesSet.First();
                        if (IFCAnyHandleUtil.IsTypeOf(relAggregates, IFCEntityType.IfcRelAggregates))
                        {
                            subElemHnds = IFCAnyHandleUtil.GetAggregateInstanceAttribute <List <IFCAnyHandle> >(relAggregates, "RelatedObjects");
                        }
                    }

                    bool hasSubElems = (subElemHnds != null && subElemHnds.Count != 0);
                    bool isRoof      = IFCAnyHandleUtil.IsTypeOf(elemHnd, IFCEntityType.IfcRoof);
                    if (!hasSubElems && !isRoof && !IFCAnyHandleUtil.IsTypeOf(elemHnd, IFCEntityType.IfcWall))
                    {
                        if (layerSetUsage == null)
                        {
                            bool flipDirSense = true;
                            if (wall != null)
                            {
                                // if we have flipped the center curve on export, we need to take that into account here.
                                // We flip the center curve on export if it is an arc and it has a negative Z direction.
                                LocationCurve locCurve = wall.Location as LocationCurve;
                                if (locCurve != null)
                                {
                                    Curve curve        = locCurve.Curve;
                                    Plane defPlane     = new Plane(XYZ.BasisX, XYZ.BasisY, XYZ.Zero);
                                    bool  curveFlipped = GeometryUtil.MustFlipCurve(defPlane, curve);
                                    flipDirSense = !(wall.Flipped ^ curveFlipped);
                                }
                            }
                            else if (hostObject is Floor)
                            {
                                flipDirSense = false;
                            }

                            double            offsetFromReferenceLine = flipDirSense ? -scaledOffset : scaledOffset;
                            IFCDirectionSense sense = flipDirSense ? IFCDirectionSense.Negative : IFCDirectionSense.Positive;

                            layerSetUsage = IFCInstanceExporter.CreateMaterialLayerSetUsage(file, materialLayerSet, direction, sense, offsetFromReferenceLine);
                        }
                        ExporterCacheManager.MaterialLayerRelationsCache.Add(layerSetUsage, elemHnd);
                    }
                    else
                    {
                        if (hasSubElems)
                        {
                            foreach (IFCAnyHandle subElemHnd in subElemHnds)
                            {
                                if (!IFCAnyHandleUtil.IsNullOrHasNoValue(subElemHnd))
                                {
                                    ExporterCacheManager.MaterialLayerRelationsCache.Add(materialLayerSet, subElemHnd);
                                }
                            }
                        }
                        else if (!isRoof)
                        {
                            ExporterCacheManager.MaterialLayerRelationsCache.Add(materialLayerSet, elemHnd);
                        }
                        else if (primaryMaterialHnd != null)
                        {
                            ExporterCacheManager.MaterialLayerRelationsCache.Add(primaryMaterialHnd, elemHnd);
                        }
                    }
                }

                tr.Commit();
                return(true);
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Exports an element as IFC railing.
        /// </summary>
        /// <param name="exporterIFC">
        /// The ExporterIFC object.
        /// </param>
        /// <param name="element">
        /// The element to be exported.
        /// </param>
        /// <param name="geometryElement">
        /// The geometry element.
        /// </param>
        /// <param name="productWrapper">
        /// The ProductWrapper.
        /// </param>
        public static void ExportRailing(ExporterIFC exporterIFC, Element element, GeometryElement geomElem, string ifcEnumType, ProductWrapper productWrapper)
        {
            // Check the intended IFC entity or type name is in the exclude list specified in the UI
            Common.Enums.IFCEntityType elementClassTypeEnum = Common.Enums.IFCEntityType.IfcRailing;
            if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum))
            {
                return;
            }

            ElementType elemType    = element.Document.GetElement(element.GetTypeId()) as ElementType;
            IFCFile     file        = exporterIFC.GetFile();
            Options     geomOptions = GeometryUtil.GetIFCExportGeometryOptions();

            using (IFCTransaction transaction = new IFCTransaction(file))
            {
                // Check for containment override
                IFCAnyHandle overrideContainerHnd = null;
                ElementId    overrideContainerId  = ParameterUtil.OverrideContainmentParameter(exporterIFC, element, out overrideContainerHnd);

                using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element, null, null, overrideContainerId, overrideContainerHnd))
                {
                    using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                    {
                        IFCAnyHandle           localPlacement = setter.LocalPlacement;
                        StairRampContainerInfo stairRampInfo  = null;
                        ElementId hostId     = GetStairOrRampHostId(exporterIFC, element as Railing);
                        Transform inverseTrf = Transform.Identity;
                        if (hostId != ElementId.InvalidElementId)
                        {
                            stairRampInfo = ExporterCacheManager.StairRampContainerInfoCache.GetStairRampContainerInfo(hostId);
                            IFCAnyHandle stairRampLocalPlacement = stairRampInfo.LocalPlacements[0];
                            Transform    relTrf = ExporterIFCUtils.GetRelativeLocalPlacementOffsetTransform(stairRampLocalPlacement, localPlacement);
                            inverseTrf = relTrf.Inverse;

                            IFCAnyHandle railingLocalPlacement = ExporterUtil.CreateLocalPlacement(file, stairRampLocalPlacement,
                                                                                                   inverseTrf.Origin, inverseTrf.BasisZ, inverseTrf.BasisX);
                            localPlacement = railingLocalPlacement;
                        }
                        ecData.SetLocalPlacement(localPlacement);

                        SolidMeshGeometryInfo  solidMeshInfo = GeometryUtil.GetSplitSolidMeshGeometry(geomElem);
                        IList <Solid>          solids        = solidMeshInfo.GetSolids();
                        IList <Mesh>           meshes        = solidMeshInfo.GetMeshes();
                        IList <GeometryObject> gObjs         = FamilyExporterUtil.RemoveInvisibleSolidsAndMeshes(element.Document, exporterIFC, ref solids, ref meshes);

                        Railing           railingElem   = element as Railing;
                        IList <ElementId> subElementIds = CollectSubElements(railingElem);

                        foreach (ElementId subElementId in subElementIds)
                        {
                            Element subElement = railingElem.Document.GetElement(subElementId);
                            if (subElement != null)
                            {
                                GeometryElement subElementGeom = GeometryUtil.GetOneLevelGeometryElement(subElement.get_Geometry(geomOptions), 0);

                                SolidMeshGeometryInfo  subElementSolidMeshInfo = GeometryUtil.GetSplitSolidMeshGeometry(subElementGeom);
                                IList <Solid>          subElemSolids           = subElementSolidMeshInfo.GetSolids();
                                IList <Mesh>           subElemMeshes           = subElementSolidMeshInfo.GetMeshes();
                                IList <GeometryObject> partGObjs = FamilyExporterUtil.RemoveInvisibleSolidsAndMeshes(element.Document, exporterIFC, ref subElemSolids, ref subElemMeshes);
                                foreach (Solid subElSolid in subElemSolids)
                                {
                                    solids.Add(subElSolid);
                                }
                                foreach (Mesh subElMesh in subElemMeshes)
                                {
                                    meshes.Add(subElMesh);
                                }
                            }
                        }

                        ElementId           catId               = CategoryUtil.GetSafeCategoryId(element);
                        BodyData            bodyData            = null;
                        BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.Medium);

                        if (solids.Count > 0 || meshes.Count > 0)
                        {
                            bodyData = BodyExporter.ExportBody(exporterIFC, element, catId, ElementId.InvalidElementId, solids, meshes, bodyExporterOptions, ecData);
                        }
                        else
                        {
                            IList <GeometryObject> geomlist = new List <GeometryObject>();
                            geomlist.Add(geomElem);
                            bodyData = BodyExporter.ExportBody(exporterIFC, element, catId, ElementId.InvalidElementId, geomlist, bodyExporterOptions, ecData);
                        }

                        IFCAnyHandle bodyRep = bodyData.RepresentationHnd;
                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep))
                        {
                            if (ecData != null)
                            {
                                ecData.ClearOpenings();
                            }
                            return;
                        }

                        IList <IFCAnyHandle> representations = new List <IFCAnyHandle>();
                        representations.Add(bodyRep);

                        IList <GeometryObject> geomObjects = new List <GeometryObject>(solids);
                        foreach (Mesh mesh in meshes)
                        {
                            geomObjects.Add(mesh);
                        }

                        Transform boundingBoxTrf = (bodyData.OffsetTransform != null) ? bodyData.OffsetTransform.Inverse : Transform.Identity;
                        boundingBoxTrf = inverseTrf.Multiply(boundingBoxTrf);
                        IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, geomObjects, boundingBoxTrf);
                        if (boundingBoxRep != null)
                        {
                            representations.Add(boundingBoxRep);
                        }

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

                        IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle;

                        string instanceGUID = GUIDUtil.CreateGUID(element);

                        IFCExportInfoPair exportInfo = ExporterUtil.GetProductExportType(exporterIFC, element, out ifcEnumType);

                        IFCAnyHandle railing = IFCInstanceExporter.CreateGenericIFCEntity(exportInfo, exporterIFC, element, instanceGUID, ownerHistory,
                                                                                          ecData.GetLocalPlacement(), prodRep);

                        bool associateToLevel = (hostId == ElementId.InvalidElementId);

                        productWrapper.AddElement(element, railing, setter, ecData, associateToLevel, exportInfo);
                        OpeningUtil.CreateOpeningsIfNecessary(railing, element, ecData, bodyData.OffsetTransform,
                                                              exporterIFC, ecData.GetLocalPlacement(), setter, productWrapper);

                        IFCAnyHandle      singleMaterialOverrideHnd = null;
                        IList <ElementId> matIds       = null;
                        ElementId         defaultMatId = ElementId.InvalidElementId;
                        ElementId         matId        = CategoryUtil.GetBaseMaterialIdForElement(element);

                        // Get IfcSingleMaterialOverride to work for railing
                        singleMaterialOverrideHnd = ExporterUtil.GetSingleMaterial(exporterIFC, element, matId);
                        if (singleMaterialOverrideHnd != null)
                        {
                            matIds = new List <ElementId> {
                                matId
                            };
                        }
                        else
                        {
                            matIds       = bodyData.MaterialIds;
                            defaultMatId = matIds[0];

                            // Check if all the items are the same, then get the first material id
                            if (matIds.All(x => x == defaultMatId))
                            {
                                matIds = new List <ElementId> {
                                    defaultMatId
                                };
                            }
                        }

                        CategoryUtil.CreateMaterialAssociationWithShapeAspect(exporterIFC, element, railing, bodyData.RepresentationItemInfo);

                        // Create multi-story duplicates of this railing.
                        if (stairRampInfo != null)
                        {
                            stairRampInfo.AddComponent(0, railing);

                            List <IFCAnyHandle> stairHandles = stairRampInfo.StairOrRampHandles;
                            for (int ii = 1; ii < stairHandles.Count; ii++)
                            {
                                IFCAnyHandle railingLocalPlacement = stairRampInfo.LocalPlacements[ii];
                                if (!IFCAnyHandleUtil.IsNullOrHasNoValue(railingLocalPlacement))
                                {
                                    IFCAnyHandle railingHndCopy = CopyRailingHandle(exporterIFC, element, catId, railingLocalPlacement, railing);
                                    stairRampInfo.AddComponent(ii, railingHndCopy);
                                    productWrapper.AddElement(element, railingHndCopy, (IFCLevelInfo)null, ecData, false, exportInfo);
                                    CategoryUtil.CreateMaterialAssociationWithShapeAspect(exporterIFC, element, railingHndCopy, bodyData.RepresentationItemInfo);
                                }
                            }

                            ExporterCacheManager.StairRampContainerInfoCache.AddStairRampContainerInfo(hostId, stairRampInfo);
                        }
                    }
                    transaction.Commit();
                }
            }
        }