Пример #1
0
        /// <summary>
        /// Exports an element as a covering of type insulation.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="element">The element.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        /// <returns>True if exported successfully, false otherwise.</returns>
        public static bool ExportDuctLining(ExporterIFC exporterIFC, Element element,
            GeometryElement geometryElement, ProductWrapper productWrapper)
        {
            if (element == null || geometryElement == null)
                return false;

            IFCFile file = exporterIFC.GetFile();

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                using (PlacementSetter placementSetter = PlacementSetter.Create(exporterIFC, element))
                {
                    using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                    {
                        ecData.SetLocalPlacement(placementSetter.LocalPlacement);

                        ElementId categoryId = CategoryUtil.GetSafeCategoryId(element);

                        BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true);
                        IFCAnyHandle representation = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, element,
                            categoryId, geometryElement, bodyExporterOptions, null, ecData, true);

                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(representation))
                        {
                            ecData.ClearOpenings();
                            return false;
                        }

                        string guid = GUIDUtil.CreateGUID(element);
                        IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle();
                        string revitObjectType = exporterIFC.GetFamilyName();
                        string name = NamingUtil.GetNameOverride(element, revitObjectType);
                        string description = NamingUtil.GetDescriptionOverride(element, null);
                        string objectType = NamingUtil.GetObjectTypeOverride(element, revitObjectType);

                        IFCAnyHandle localPlacement = ecData.GetLocalPlacement();
                        string elementTag = NamingUtil.GetTagOverride(element, NamingUtil.CreateIFCElementId(element));

                        IFCAnyHandle ductLining = IFCInstanceExporter.CreateCovering(file, guid,
                            ownerHistory, name, description, objectType, localPlacement, representation, elementTag, "Wrapping");
                        ExporterCacheManager.ElementToHandleCache.Register(element.Id, ductLining);

                        productWrapper.AddElement(element, ductLining, placementSetter.LevelInfo, ecData, true);

                        ElementId matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geometryElement, exporterIFC, element);
                        CategoryUtil.CreateMaterialAssociation(exporterIFC, ductLining, matId);
                    }
                }
                tr.Commit();
                return true;
            }
        }
        /// <summary>
        /// Exports an element as building element proxy.
        /// </summary>
        /// <remarks>
        /// This function is called from the Export function, but can also be called directly if you do not
        /// want CreateInternalPropertySets to be called.
        /// </remarks>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="element">The element.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        /// <returns>The handle if created, null otherwise.</returns>
        public static IFCAnyHandle ExportBuildingElementProxy(ExporterIFC exporterIFC, Element element,
            GeometryElement geometryElement, ProductWrapper productWrapper)
        {
            if (element == null || geometryElement == null)
                return null;

            IFCFile file = exporterIFC.GetFile();
            IFCAnyHandle buildingElementProxy = null;
            using (IFCTransaction tr = new IFCTransaction(file))
            {
                using (PlacementSetter placementSetter = PlacementSetter.Create(exporterIFC, element))
                {
                    using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                    {
                        ecData.SetLocalPlacement(placementSetter.LocalPlacement);

                        ElementId categoryId = CategoryUtil.GetSafeCategoryId(element);

                        BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true);
                        IFCAnyHandle representation = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, element,
                            categoryId, geometryElement, bodyExporterOptions, null, ecData, true);

                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(representation))
                        {
                            ecData.ClearOpenings();
                            return null;
                        }

                        string guid = GUIDUtil.CreateGUID(element);
                        IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle;
                        string revitObjectType = exporterIFC.GetFamilyName();
                        string name = NamingUtil.GetNameOverride(element, revitObjectType);
                        string description = NamingUtil.GetDescriptionOverride(element, null);
                        string objectType = NamingUtil.GetObjectTypeOverride(element, revitObjectType);

                        IFCAnyHandle localPlacement = ecData.GetLocalPlacement();
                        string elementTag = NamingUtil.GetTagOverride(element, NamingUtil.CreateIFCElementId(element));

                        buildingElementProxy = IFCInstanceExporter.CreateBuildingElementProxy(file, guid,
                            ownerHistory, name, description, objectType, localPlacement, representation, elementTag, null);

                        productWrapper.AddElement(element, buildingElementProxy, placementSetter.LevelInfo, ecData, true);
                    }
                    tr.Commit();
                }
            }

            return buildingElementProxy;
        }
Пример #3
0
        /// <summary>
        /// Exports a gutter element.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="element">The element.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        public static void ExportGutter(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, ProductWrapper productWrapper)
        {
            IFCFile file = exporterIFC.GetFile();

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element))
                {
                    using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                    {
                        ecData.SetLocalPlacement(setter.LocalPlacement);

                        ElementId categoryId = CategoryUtil.GetSafeCategoryId(element);

                        BodyExporterOptions bodyExporterOptions = new BodyExporterOptions();
                        IFCAnyHandle        bodyRep             = BodyExporter.ExportBody(exporterIFC, element, categoryId, ElementId.InvalidElementId,
                                                                                          geometryElement, bodyExporterOptions, ecData).RepresentationHnd;
                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep))
                        {
                            if (ecData != null)
                            {
                                ecData.ClearOpenings();
                            }
                            return;
                        }

                        IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle();
                        string       originalTag  = NamingUtil.CreateIFCElementId(element);

                        // In Revit, we don't have a corresponding type, so we create one for every gutter.
                        IFCAnyHandle        origin      = ExporterUtil.CreateAxis2Placement3D(file);
                        IFCAnyHandle        repMap3dHnd = IFCInstanceExporter.CreateRepresentationMap(file, origin, bodyRep);
                        List <IFCAnyHandle> repMapList  = new List <IFCAnyHandle>();
                        repMapList.Add(repMap3dHnd);
                        string elementTypeName = NamingUtil.CreateIFCObjectName(exporterIFC, element);

                        string       typeGuid = GUIDUtil.CreateSubElementGUID(element, (int)IFCHostedSweepSubElements.PipeSegmentType);
                        IFCAnyHandle style    = IFCInstanceExporter.CreatePipeSegmentType(file, typeGuid, ownerHistory,
                                                                                          elementTypeName, null, null, null, repMapList, originalTag,
                                                                                          elementTypeName, IFCPipeSegmentType.Gutter);

                        List <IFCAnyHandle> representationMaps = GeometryUtil.GetRepresentationMaps(style);
                        IFCAnyHandle        mappedItem         = ExporterUtil.CreateDefaultMappedItem(file, representationMaps[0]);

                        ISet <IFCAnyHandle> representations = new HashSet <IFCAnyHandle>();
                        representations.Add(mappedItem);

                        IFCAnyHandle bodyMappedItemRep = RepresentationUtil.CreateBodyMappedItemRep(exporterIFC,
                                                                                                    element, categoryId, exporterIFC.Get3DContextHandle("Body"), representations);
                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyMappedItemRep))
                        {
                            return;
                        }

                        List <IFCAnyHandle> shapeReps = new List <IFCAnyHandle>();
                        shapeReps.Add(bodyMappedItemRep);

                        IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, geometryElement, Transform.Identity);
                        if (boundingBoxRep != null)
                        {
                            shapeReps.Add(boundingBoxRep);
                        }

                        IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps);
                        IFCAnyHandle localPlacementToUse;
                        ElementId    roomId = setter.UpdateRoomRelativeCoordinates(element, out localPlacementToUse);
                        if (roomId == ElementId.InvalidElementId)
                        {
                            localPlacementToUse = ecData.GetLocalPlacement();
                        }

                        string guid        = GUIDUtil.CreateGUID(element);
                        string name        = NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element));
                        string description = NamingUtil.GetDescriptionOverride(element, null);
                        string objectType  = NamingUtil.GetObjectTypeOverride(element, elementTypeName);
                        string tag         = NamingUtil.GetTagOverride(element, originalTag);

                        IFCAnyHandle elemHnd = IFCInstanceExporter.CreateFlowSegment(file, guid,
                                                                                     ownerHistory, name, description, objectType, localPlacementToUse, prodRep, tag);

                        bool containedInSpace = (roomId != ElementId.InvalidElementId);
                        productWrapper.AddElement(element, elemHnd, setter.LevelInfo, ecData, !containedInSpace);

                        if (containedInSpace)
                        {
                            ExporterCacheManager.SpaceInfoCache.RelateToSpace(roomId, elemHnd);
                        }

                        // Associate segment with type.
                        ExporterCacheManager.TypeRelationsCache.Add(style, elemHnd);

                        OpeningUtil.CreateOpeningsIfNecessary(elemHnd, element, ecData, null,
                                                              exporterIFC, localPlacementToUse, setter, productWrapper);
                    }

                    tr.Commit();
                }
            }
        }
Пример #4
0
        /// <summary>
        /// Exports a CeilingAndFloor element to IFC.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="floor">The floor element.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        public static void ExportCeilingAndFloorElement(ExporterIFC exporterIFC, CeilingAndFloor floorElement, GeometryElement geometryElement,
                                                        ProductWrapper productWrapper)
        {
            if (geometryElement == null)
            {
                return;
            }

            // export parts or not
            bool exportParts = PartExporter.CanExportParts(floorElement);

            if (exportParts && !PartExporter.CanExportElementInPartExport(floorElement, floorElement.LevelId, false))
            {
                return;
            }

            string        ifcEnumType;
            IFCExportType exportType = ExporterUtil.GetExportType(exporterIFC, floorElement, out ifcEnumType);

            IFCFile file = exporterIFC.GetFile();
            IList <IFCAnyHandle> slabHnds        = new List <IFCAnyHandle>();
            IList <IFCAnyHandle> brepSlabHnds    = new List <IFCAnyHandle>();
            IList <IFCAnyHandle> nonBrepSlabHnds = new List <IFCAnyHandle>();

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                using (IFCTransformSetter transformSetter = IFCTransformSetter.Create())
                {
                    using (PlacementSetter placementSetter = PlacementSetter.Create(exporterIFC, floorElement))
                    {
                        IFCAnyHandle localPlacement = placementSetter.LocalPlacement;
                        IFCAnyHandle ownerHistory   = exporterIFC.GetOwnerHistoryHandle();
                        bool         exportedAsInternalExtrusion = false;

                        ElementId catId = CategoryUtil.GetSafeCategoryId(floorElement);

                        IList <IFCAnyHandle>             prodReps        = new List <IFCAnyHandle>();
                        IList <ShapeRepresentationType>  repTypes        = new List <ShapeRepresentationType>();
                        IList <IList <CurveLoop> >       extrusionLoops  = new List <IList <CurveLoop> >();
                        IList <IFCExtrusionCreationData> loopExtraParams = new List <IFCExtrusionCreationData>();
                        Plane floorPlane = GeometryUtil.CreateDefaultPlane();

                        IList <IFCAnyHandle> localPlacements = new List <IFCAnyHandle>();

                        if (!exportParts && (floorElement is Floor))
                        {
                            Floor floor = floorElement as Floor;

                            // First, try to use the ExtrusionAnalyzer for the limited cases it handles - 1 solid, no openings, end clippings only.
                            // Also limited to cases with line and arc boundaries.
                            //
                            SolidMeshGeometryInfo solidMeshInfo = GeometryUtil.GetSplitSolidMeshGeometry(geometryElement);
                            IList <Solid>         solids        = solidMeshInfo.GetSolids();
                            IList <Mesh>          meshes        = solidMeshInfo.GetMeshes();

                            if (solids.Count == 1 && meshes.Count == 0)
                            {
                                bool completelyClipped;
                                XYZ  floorExtrusionDirection = new XYZ(0, 0, -1);
                                XYZ  modelOrigin             = XYZ.Zero;

                                XYZ floorOrigin = floor.GetVerticalProjectionPoint(modelOrigin, FloorFace.Top);
                                if (floorOrigin == null)
                                {
                                    // GetVerticalProjectionPoint may return null if FloorFace.Top is an edited face that doesn't
                                    // go thruough te Revit model orgigin.  We'll try the midpoint of the bounding box instead.
                                    BoundingBoxXYZ boundingBox = floorElement.get_BoundingBox(null);
                                    modelOrigin = (boundingBox.Min + boundingBox.Max) / 2.0;
                                    floorOrigin = floor.GetVerticalProjectionPoint(modelOrigin, FloorFace.Top);
                                }

                                if (floorOrigin != null)
                                {
                                    XYZ   floorDir = floor.GetNormalAtVerticalProjectionPoint(floorOrigin, FloorFace.Top);
                                    Plane extrusionAnalyzerFloorPlane = new Plane(floorDir, floorOrigin);

                                    HandleAndData floorAndProperties =
                                        ExtrusionExporter.CreateExtrusionWithClippingAndProperties(exporterIFC, floorElement,
                                                                                                   catId, solids[0], extrusionAnalyzerFloorPlane, floorExtrusionDirection, null, out completelyClipped);
                                    if (completelyClipped)
                                    {
                                        return;
                                    }
                                    if (floorAndProperties.Handle != null)
                                    {
                                        IList <IFCAnyHandle> representations = new List <IFCAnyHandle>();
                                        representations.Add(floorAndProperties.Handle);
                                        IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, representations);
                                        prodReps.Add(prodRep);
                                        repTypes.Add(ShapeRepresentationType.SweptSolid);

                                        if (floorAndProperties.Data != null)
                                        {
                                            loopExtraParams.Add(floorAndProperties.Data);
                                        }
                                    }
                                }
                            }
                        }

                        // Use internal routine as backup that handles openings.
                        if (prodReps.Count == 0)
                        {
                            exportedAsInternalExtrusion = ExporterIFCUtils.ExportSlabAsExtrusion(exporterIFC, floorElement,
                                                                                                 geometryElement, transformSetter, localPlacement, out localPlacements, out prodReps,
                                                                                                 out extrusionLoops, out loopExtraParams, floorPlane);
                            for (int ii = 0; ii < prodReps.Count; ii++)
                            {
                                // all are extrusions
                                repTypes.Add(ShapeRepresentationType.SweptSolid);
                            }
                        }

                        if (prodReps.Count == 0)
                        {
                            using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                            {
                                BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true);
                                bodyExporterOptions.TessellationLevel = BodyExporter.GetTessellationLevel();
                                BodyData     bodyData;
                                IFCAnyHandle prodDefHnd = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC,
                                                                                                                     floorElement, catId, geometryElement, bodyExporterOptions, null, ecData, out bodyData);
                                if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodDefHnd))
                                {
                                    ecData.ClearOpenings();
                                    return;
                                }

                                prodReps.Add(prodDefHnd);
                                repTypes.Add(bodyData.ShapeRepresentationType);
                            }
                        }

                        // Create the slab from either the extrusion or the BRep information.
                        string ifcGUID = GUIDUtil.CreateGUID(floorElement);

                        int numReps = exportParts ? 1 : prodReps.Count;

                        string entityType = null;

                        switch (exportType)
                        {
                        case IFCExportType.IfcFooting:
                            if (ExporterCacheManager.ExportOptionsCache.ExportAs4)
                            {
                                entityType = IFCValidateEntry.GetValidIFCType <Revit.IFC.Export.Toolkit.IFC4.IFCFootingType>(floorElement, ifcEnumType, null);
                            }
                            else
                            {
                                entityType = IFCValidateEntry.GetValidIFCType <IFCFootingType>(floorElement, ifcEnumType, null);
                            }
                            break;

                        case IFCExportType.IfcCovering:
                            entityType = IFCValidateEntry.GetValidIFCType <IFCCoveringType>(floorElement, ifcEnumType, "FLOORING");
                            break;

                        case IFCExportType.IfcRamp:
                            if (ExporterCacheManager.ExportOptionsCache.ExportAs4)
                            {
                                entityType = IFCValidateEntry.GetValidIFCType <Revit.IFC.Export.Toolkit.IFC4.IFCRampType>(floorElement, ifcEnumType, null);
                            }
                            else
                            {
                                entityType = IFCValidateEntry.GetValidIFCType <IFCRampType>(floorElement, ifcEnumType, null);
                            }
                            break;

                        default:
                            bool            isBaseSlab      = false;
                            AnalyticalModel analyticalModel = floorElement.GetAnalyticalModel();
                            if (analyticalModel != null)
                            {
                                AnalyzeAs slabFoundationType = analyticalModel.GetAnalyzeAs();
                                isBaseSlab = (slabFoundationType == AnalyzeAs.SlabOnGrade) || (slabFoundationType == AnalyzeAs.Mat);
                            }
                            entityType = IFCValidateEntry.GetValidIFCType <IFCSlabType>(floorElement, ifcEnumType, isBaseSlab ? "BASESLAB" : "FLOOR");
                            break;
                        }

                        for (int ii = 0; ii < numReps; ii++)
                        {
                            string ifcName        = NamingUtil.GetNameOverride(floorElement, NamingUtil.GetIFCNamePlusIndex(floorElement, ii == 0 ? -1 : ii + 1));
                            string ifcDescription = NamingUtil.GetDescriptionOverride(floorElement, null);
                            string ifcObjectType  = NamingUtil.GetObjectTypeOverride(floorElement, exporterIFC.GetFamilyName());
                            string ifcTag         = NamingUtil.GetTagOverride(floorElement, NamingUtil.CreateIFCElementId(floorElement));

                            string       currentGUID       = (ii == 0) ? ifcGUID : GUIDUtil.CreateGUID();
                            IFCAnyHandle localPlacementHnd = exportedAsInternalExtrusion ? localPlacements[ii] : localPlacement;

                            IFCAnyHandle slabHnd = null;

                            // TODO: replace with CreateGenericBuildingElement.
                            switch (exportType)
                            {
                            case IFCExportType.IfcFooting:
                                slabHnd = IFCInstanceExporter.CreateFooting(file, currentGUID, ownerHistory, ifcName,
                                                                            ifcDescription, ifcObjectType, localPlacementHnd, exportParts ? null : prodReps[ii],
                                                                            ifcTag, entityType);
                                break;

                            case IFCExportType.IfcCovering:
                                slabHnd = IFCInstanceExporter.CreateCovering(file, currentGUID, ownerHistory, ifcName,
                                                                             ifcDescription, ifcObjectType, localPlacementHnd, exportParts ? null : prodReps[ii],
                                                                             ifcTag, entityType);
                                break;

                            case IFCExportType.IfcRamp:
                                slabHnd = IFCInstanceExporter.CreateRamp(file, currentGUID, ownerHistory, ifcName,
                                                                         ifcDescription, ifcObjectType, localPlacementHnd, exportParts ? null : prodReps[ii],
                                                                         ifcTag, entityType);
                                break;

                            default:
                                slabHnd = IFCInstanceExporter.CreateSlab(file, currentGUID, ownerHistory, ifcName,
                                                                         ifcDescription, ifcObjectType, localPlacementHnd, exportParts ? null : prodReps[ii],
                                                                         ifcTag, entityType);
                                break;
                            }

                            if (IFCAnyHandleUtil.IsNullOrHasNoValue(slabHnd))
                            {
                                return;
                            }

                            if (exportParts)
                            {
                                PartExporter.ExportHostPart(exporterIFC, floorElement, slabHnd, productWrapper, placementSetter, localPlacementHnd, null);
                            }

                            slabHnds.Add(slabHnd);

                            if (!exportParts)
                            {
                                if (repTypes[ii] == ShapeRepresentationType.Brep)
                                {
                                    brepSlabHnds.Add(slabHnd);
                                }
                                else
                                {
                                    nonBrepSlabHnds.Add(slabHnd);
                                }
                            }
                        }

                        for (int ii = 0; ii < numReps; ii++)
                        {
                            IFCExtrusionCreationData loopExtraParam = ii < loopExtraParams.Count ? loopExtraParams[ii] : null;
                            productWrapper.AddElement(floorElement, slabHnds[ii], placementSetter, loopExtraParam, true);
                        }

                        if (exportedAsInternalExtrusion)
                        {
                            ExporterIFCUtils.ExportExtrudedSlabOpenings(exporterIFC, floorElement, placementSetter.LevelInfo,
                                                                        localPlacements[0], slabHnds, extrusionLoops, floorPlane, productWrapper.ToNative());
                        }
                    }

                    if (!exportParts)
                    {
                        if (nonBrepSlabHnds.Count > 0)
                        {
                            HostObjectExporter.ExportHostObjectMaterials(exporterIFC, floorElement, nonBrepSlabHnds,
                                                                         geometryElement, productWrapper, ElementId.InvalidElementId, Toolkit.IFCLayerSetDirection.Axis3, false);
                        }
                        if (brepSlabHnds.Count > 0)
                        {
                            HostObjectExporter.ExportHostObjectMaterials(exporterIFC, floorElement, brepSlabHnds,
                                                                         geometryElement, productWrapper, ElementId.InvalidElementId, Toolkit.IFCLayerSetDirection.Axis3, true);
                        }
                    }
                }
                tr.Commit();

                return;
            }
        }
Пример #5
0
        /// <summary>
        /// Exports mullion.
        /// </summary>
        /// <param name="exporterIFC">
        /// The ExporterIFC object.
        /// </param>
        /// <param name="mullion">
        /// The mullion object.
        /// </param>
        /// <param name="geometryElement">
        /// The geometry element.
        /// </param>
        /// <param name="localPlacement">
        /// The local placement handle.
        /// </param>
        /// <param name="setter">
        /// The PlacementSetter.
        /// </param>
        /// <param name="productWrapper">
        /// The ProductWrapper.
        /// </param>
        public static void Export(ExporterIFC exporterIFC, Mullion mullion, GeometryElement geometryElement,
                                  IFCAnyHandle localPlacement, PlacementSetter setter, ProductWrapper productWrapper)
        {
            IFCFile file = exporterIFC.GetFile();

            using (PlacementSetter mullionSetter = PlacementSetter.Create(exporterIFC, mullion))
            {
                using (IFCExtrusionCreationData extraParams = new IFCExtrusionCreationData())
                {
                    IFCAnyHandle mullionPlacement = mullionSetter.LocalPlacement;

                    Transform relTrf     = ExporterIFCUtils.GetRelativeLocalPlacementOffsetTransform(localPlacement, mullionPlacement);
                    Transform inverseTrf = relTrf.Inverse;

                    IFCAnyHandle mullionLocalPlacement = ExporterUtil.CreateLocalPlacement(file, localPlacement,
                                                                                           inverseTrf.Origin, inverseTrf.BasisZ, inverseTrf.BasisX);

                    extraParams.SetLocalPlacement(mullionLocalPlacement);

                    Transform extrusionLCS = null;
                    // Add a custom direction for trying to create an extrusion based on the base curve of the mullion, if it is a line and not an arc.
                    Curve baseCurve = mullion.LocationCurve;
                    if ((baseCurve != null) && (baseCurve is Line))
                    {
                        // We won't use curveBounds and origin yet; just need the axis for now.
                        IFCRange curveBounds;
                        XYZ      origin, mullionDirection;
                        GeometryUtil.GetAxisAndRangeFromCurve(baseCurve, out curveBounds, out mullionDirection, out origin);

                        // approx 1.0/sqrt(2.0)
                        XYZ planeY = (Math.Abs(mullionDirection.Z) < 0.707) ? XYZ.BasisZ.CrossProduct(mullionDirection) : XYZ.BasisX.CrossProduct(mullionDirection);
                        planeY.Normalize();

                        XYZ projDir = mullionDirection.CrossProduct(planeY);

                        extrusionLCS        = Transform.Identity;
                        extrusionLCS.BasisX = mullionDirection; extrusionLCS.BasisY = planeY; extrusionLCS.BasisZ = projDir; extrusionLCS.Origin = origin;
                    }

                    ElementId catId = CategoryUtil.GetSafeCategoryId(mullion);

                    BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true);
                    bodyExporterOptions.ExtrusionLocalCoordinateSystem = extrusionLCS;

                    IFCAnyHandle repHnd = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, mullion, catId,
                                                                                                     geometryElement, bodyExporterOptions, null, extraParams, true);
                    if (IFCAnyHandleUtil.IsNullOrHasNoValue(repHnd))
                    {
                        extraParams.ClearOpenings();
                        return;
                    }

                    string       elemGUID       = GUIDUtil.CreateGUID(mullion);
                    IFCAnyHandle ownerHistory   = exporterIFC.GetOwnerHistoryHandle();
                    string       elemObjectType = NamingUtil.CreateIFCObjectName(exporterIFC, mullion);
                    string       name           = NamingUtil.GetNameOverride(mullion, elemObjectType);
                    string       description    = NamingUtil.GetDescriptionOverride(mullion, null);
                    string       objectType     = NamingUtil.GetObjectTypeOverride(mullion, elemObjectType);
                    string       elemTag        = NamingUtil.GetTagOverride(mullion, NamingUtil.CreateIFCElementId(mullion));

                    IFCAnyHandle mullionHnd = IFCInstanceExporter.CreateMember(file, elemGUID, ownerHistory, name, description, objectType,
                                                                               mullionLocalPlacement, repHnd, elemTag, "MULLION");
                    ExporterCacheManager.HandleToElementCache.Register(mullionHnd, mullion.Id);

                    productWrapper.AddElement(mullion, mullionHnd, mullionSetter, extraParams, false);

                    ElementId matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geometryElement, exporterIFC, mullion);
                    CategoryUtil.CreateMaterialAssociation(exporterIFC, mullionHnd, matId);
                }
            }
        }
        /// <summary>
        /// Creates a SweptSolid, Brep, or Surface product definition shape representation, depending on the geoemtry and export version.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="categoryId">The category id.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="bodyExporterOptions">The body exporter options.</param>
        /// <param name="extraReps">Extra representations (e.g. Axis, Boundary).  May be null.</param>
        /// <param name="extrusionCreationData">The extrusion creation data.</param>
        /// <param name="allowOffsetTransform">Allows local coordinate system to be placed close to geometry.</param>
        /// <returns>The handle.</returns>
        /// <remarks>allowOffsetTransform should only be set to true if no other associated geometry is going to be exported.  Otherwise,
        /// there could be an offset between this geometry and the other, non-transformed, geometry.</remarks>
        public static IFCAnyHandle CreateAppropriateProductDefinitionShape(ExporterIFC exporterIFC, Element element, ElementId categoryId,
            GeometryElement geometryElement, BodyExporterOptions bodyExporterOptions, IList<IFCAnyHandle> extraReps,
            IFCExtrusionCreationData extrusionCreationData, bool allowOffsetTransform)
        {
            BodyData bodyData;
            BodyExporterOptions newBodyExporterOptions = new BodyExporterOptions(bodyExporterOptions);
            newBodyExporterOptions.AllowOffsetTransform = allowOffsetTransform;

            return CreateAppropriateProductDefinitionShape(exporterIFC, element, categoryId,
                geometryElement, newBodyExporterOptions, extraReps, extrusionCreationData, out bodyData);
        }
Пример #7
0
        /// <summary>
        /// Exports a geometry element to boundary representation.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="element">The element.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="exportBoundaryRep">True if to export boundary representation.</param>
        /// <param name="exportAsFacetation">True if to export the geometry as facetation.</param>
        /// <param name="bodyRep">Body representation.</param>
        /// <param name="boundaryRep">Boundary representation.</param>
        /// <returns>True if success, false if fail.</returns>
        public static bool ExportSurface(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement,
                                         bool exportBoundaryRep, bool exportAsFacetation, ref IFCAnyHandle bodyRep, ref IFCAnyHandle boundaryRep)
        {
            if (geometryElement == null)
            {
                return(false);
            }

            IFCGeometryInfo ifcGeomInfo = null;
            Document        doc         = element.Document;
            Plane           plane       = GeometryUtil.CreateDefaultPlane();
            XYZ             projDir     = new XYZ(0, 0, 1);
            double          eps         = UnitUtil.ScaleLength(doc.Application.VertexTolerance);

            ifcGeomInfo = IFCGeometryInfo.CreateFaceGeometryInfo(exporterIFC, plane, projDir, eps, exportBoundaryRep);

            ExporterIFCUtils.CollectGeometryInfo(exporterIFC, ifcGeomInfo, geometryElement, XYZ.Zero, true);

            IFCFile      file = exporterIFC.GetFile();
            IFCAnyHandle surface;

            // Use tessellated geometry for surface in IFC Reference View
            if (ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView)
            {
                BodyExporterOptions options = new BodyExporterOptions(false, ExportOptionsCache.ExportTessellationLevel.ExtraLow);
                surface = BodyExporter.ExportBodyAsTriangulatedFaceSet(exporterIFC, element, options, geometryElement);
            }
            else
            {
                HashSet <IFCAnyHandle> faceSets = new HashSet <IFCAnyHandle>();
                IList <ICollection <IFCAnyHandle> > faceList = ifcGeomInfo.GetFaces();
                foreach (ICollection <IFCAnyHandle> faces in faceList)
                {
                    // no faces, don't complain.
                    if (faces.Count == 0)
                    {
                        continue;
                    }
                    HashSet <IFCAnyHandle> faceSet = new HashSet <IFCAnyHandle>(faces);
                    faceSets.Add(IFCInstanceExporter.CreateConnectedFaceSet(file, faceSet));
                }

                if (faceSets.Count == 0)
                {
                    return(false);
                }

                surface = IFCInstanceExporter.CreateFaceBasedSurfaceModel(file, faceSets);
            }

            if (IFCAnyHandleUtil.IsNullOrHasNoValue(surface))
            {
                return(false);
            }

            BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, doc, surface, BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geometryElement, exporterIFC, element));

            ISet <IFCAnyHandle> surfaceItems = new HashSet <IFCAnyHandle>();

            surfaceItems.Add(surface);

            ElementId catId = CategoryUtil.GetSafeCategoryId(element);

            bodyRep = RepresentationUtil.CreateSurfaceRep(exporterIFC, element, catId, exporterIFC.Get3DContextHandle("Body"), surfaceItems,
                                                          exportAsFacetation, bodyRep);
            if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep))
            {
                return(false);
            }

            ICollection <IFCAnyHandle> boundaryRepresentations = ifcGeomInfo.GetRepresentations();

            if (exportBoundaryRep && boundaryRepresentations.Count > 0)
            {
                HashSet <IFCAnyHandle> boundaryRepresentationSet = new HashSet <IFCAnyHandle>();
                boundaryRepresentationSet.UnionWith(boundaryRepresentations);
                boundaryRep = RepresentationUtil.CreateBoundaryRep(exporterIFC, element, catId, exporterIFC.Get3DContextHandle("FootPrint"), boundaryRepresentationSet,
                                                                   boundaryRep);
            }

            return(true);
        }
Пример #8
0
        /// <summary>
        /// Export the individual part (IfcBuildingElementPart).
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="partElement">The part element to export.</param>
        /// <param name="geometryElement">The geometry of part.</param>
        /// <param name="productWrapper">The ProductWrapper object.</param>
        public static void ExportPart(ExporterIFC exporterIFC, Element partElement, ProductWrapper productWrapper,
                                      PlacementSetter placementSetter, IFCAnyHandle originalPlacement, IFCRange range, IFCExtrusionAxes ifcExtrusionAxes,
                                      Element hostElement, ElementId overrideLevelId, bool asBuildingElement)
        {
            if (!ElementFilteringUtil.IsElementVisible(partElement))
            {
                return;
            }

            Part part = partElement as Part;

            if (part == null)
            {
                return;
            }

            PlacementSetter standalonePlacementSetter = null;
            bool            standaloneExport          = hostElement == null && !asBuildingElement;

            ElementId partExportLevel = null;

            if (standaloneExport || asBuildingElement)
            {
                partExportLevel = partElement.LevelId;
            }
            else
            {
                if (part.OriginalCategoryId != hostElement.Category.Id)
                {
                    return;
                }
                partExportLevel = hostElement.LevelId;
            }
            if (overrideLevelId != null)
            {
                partExportLevel = overrideLevelId;
            }

            if (ExporterCacheManager.PartExportedCache.HasExported(partElement.Id, partExportLevel))
            {
                return;
            }

            Options options   = GeometryUtil.GetIFCExportGeometryOptions();
            View    ownerView = partElement.Document.GetElement(partElement.OwnerViewId) as View;

            if (ownerView != null)
            {
                options.View = ownerView;
            }

            GeometryElement geometryElement = partElement.get_Geometry(options);

            if (geometryElement == null)
            {
                return;
            }

            try
            {
                IFCFile file = exporterIFC.GetFile();
                using (IFCTransaction transaction = new IFCTransaction(file))
                {
                    IFCAnyHandle partPlacement = null;
                    if (standaloneExport || asBuildingElement)
                    {
                        Transform orientationTrf = Transform.Identity;
                        standalonePlacementSetter = PlacementSetter.Create(exporterIFC, partElement, null, orientationTrf, partExportLevel);
                        partPlacement             = standalonePlacementSetter.LocalPlacement;
                    }
                    else
                    {
                        partPlacement = ExporterUtil.CreateLocalPlacement(file, originalPlacement, null);
                    }

                    bool validRange = (range != null && !MathUtil.IsAlmostZero(range.Start - range.End));

                    SolidMeshGeometryInfo solidMeshInfo;
                    if (validRange)
                    {
                        solidMeshInfo = GeometryUtil.GetSplitClippedSolidMeshGeometry(geometryElement, range);
                        if (solidMeshInfo.GetSolids().Count == 0 && solidMeshInfo.GetMeshes().Count == 0)
                        {
                            return;
                        }
                    }
                    else
                    {
                        solidMeshInfo = GeometryUtil.GetSplitSolidMeshGeometry(geometryElement);
                    }

                    using (IFCExtrusionCreationData extrusionCreationData = new IFCExtrusionCreationData())
                    {
                        extrusionCreationData.SetLocalPlacement(partPlacement);
                        extrusionCreationData.ReuseLocalPlacement   = false;
                        extrusionCreationData.PossibleExtrusionAxes = ifcExtrusionAxes;

                        IList <Solid> solids = solidMeshInfo.GetSolids();
                        IList <Mesh>  meshes = solidMeshInfo.GetMeshes();

                        ElementId catId     = CategoryUtil.GetSafeCategoryId(partElement);
                        ElementId hostCatId = CategoryUtil.GetSafeCategoryId(hostElement);

                        BodyData            bodyData            = null;
                        BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true);
                        if (solids.Count > 0 || meshes.Count > 0)
                        {
                            bodyData = BodyExporter.ExportBody(exporterIFC, partElement, catId, ElementId.InvalidElementId, solids, meshes,
                                                               bodyExporterOptions, extrusionCreationData);
                        }
                        else
                        {
                            IList <GeometryObject> geomlist = new List <GeometryObject>();
                            geomlist.Add(geometryElement);
                            bodyData = BodyExporter.ExportBody(exporterIFC, partElement, catId, ElementId.InvalidElementId, geomlist,
                                                               bodyExporterOptions, extrusionCreationData);
                        }

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

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

                        IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, geometryElement, Transform.Identity);
                        if (boundingBoxRep != null)
                        {
                            representations.Add(boundingBoxRep);
                        }

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

                        IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle();

                        string partGUID        = GUIDUtil.CreateGUID(partElement);
                        string partName        = NamingUtil.GetNameOverride(partElement, NamingUtil.GetIFCName(partElement));
                        string partDescription = NamingUtil.GetDescriptionOverride(partElement, null);
                        string partObjectType  = NamingUtil.GetObjectTypeOverride(partElement, NamingUtil.CreateIFCObjectName(exporterIFC, partElement));
                        string partTag         = NamingUtil.GetTagOverride(partElement, NamingUtil.CreateIFCElementId(partElement));

                        IFCAnyHandle ifcPart = null;
                        if (!asBuildingElement)
                        {
                            ifcPart = IFCInstanceExporter.CreateBuildingElementPart(file, partGUID, ownerHistory, partName, partDescription,
                                                                                    partObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, partTag);
                        }
                        else
                        {
                            string        ifcEnumType = null;
                            IFCExportType exportType  = ExporterUtil.GetExportType(exporterIFC, hostElement, out ifcEnumType);

                            string defaultValue = null;
                            // This replicates old functionality before IFC4 addition, where the default for slab was "FLOOR".
                            // Really the export layer table should be fixed for this case.
                            if (string.IsNullOrWhiteSpace(ifcEnumType) && hostCatId == new ElementId(BuiltInCategory.OST_Floors))
                            {
                                ifcEnumType = "FLOOR";
                            }
                            ifcEnumType = IFCValidateEntry.GetValidIFCType(hostElement, ifcEnumType, defaultValue);

                            switch (exportType)
                            {
                            case IFCExportType.IfcColumnType:
                                ifcPart = IFCInstanceExporter.CreateColumn(file, partGUID, ownerHistory, partName, partDescription, partObjectType,
                                                                           extrusionCreationData.GetLocalPlacement(), prodRep, partTag, ifcEnumType);
                                break;

                            case IFCExportType.IfcCovering:
                                ifcPart = IFCInstanceExporter.CreateCovering(file, partGUID, ownerHistory, partName, partDescription, partObjectType,
                                                                             extrusionCreationData.GetLocalPlacement(), prodRep, partTag, ifcEnumType);
                                break;

                            case IFCExportType.IfcFooting:
                                ifcPart = IFCInstanceExporter.CreateFooting(file, partGUID, ownerHistory, partName, partDescription, partObjectType,
                                                                            extrusionCreationData.GetLocalPlacement(), prodRep, partTag, ifcEnumType);
                                break;

                            case IFCExportType.IfcPile:
                                ifcPart = IFCInstanceExporter.CreatePile(file, partGUID, ownerHistory, partName, partDescription, partObjectType,
                                                                         extrusionCreationData.GetLocalPlacement(), prodRep, partTag, ifcEnumType, null);
                                break;

                            case IFCExportType.IfcRoof:
                                ifcPart = IFCInstanceExporter.CreateRoof(file, partGUID, ownerHistory, partName, partDescription, partObjectType,
                                                                         extrusionCreationData.GetLocalPlacement(), prodRep, partTag, ifcEnumType);
                                break;

                            case IFCExportType.IfcSlab:
                                ifcPart = IFCInstanceExporter.CreateSlab(file, partGUID, ownerHistory, partName, partDescription, partObjectType,
                                                                         extrusionCreationData.GetLocalPlacement(), prodRep, partTag, ifcEnumType);
                                break;

                            case IFCExportType.IfcWall:
                                ifcPart = IFCInstanceExporter.CreateWall(file, partGUID, ownerHistory, partName, partDescription, partObjectType,
                                                                         extrusionCreationData.GetLocalPlacement(), prodRep, partTag, ifcEnumType);
                                break;

                            default:
                                ifcPart = IFCInstanceExporter.CreateBuildingElementProxy(file, partGUID, ownerHistory, partName, partDescription,
                                                                                         partObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, partTag, null);
                                break;
                            }
                        }

                        bool            containedInLevel     = (standaloneExport || asBuildingElement);
                        PlacementSetter whichPlacementSetter = containedInLevel ? standalonePlacementSetter : placementSetter;
                        productWrapper.AddElement(partElement, ifcPart, whichPlacementSetter, extrusionCreationData, containedInLevel);

                        //Add the exported part to exported cache.
                        TraceExportedParts(partElement, partExportLevel, standaloneExport || asBuildingElement ? ElementId.InvalidElementId : hostElement.Id);

                        CategoryUtil.CreateMaterialAssociations(exporterIFC, ifcPart, bodyData.MaterialIds);

                        transaction.Commit();
                    }
                }
            }
            finally
            {
                if (standalonePlacementSetter != null)
                {
                    standalonePlacementSetter.Dispose();
                }
            }
        }
        /// <summary>
        /// Main implementation to export walls.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="element">The element.</param>
        /// <param name="connectedWalls">Information about walls joined to this wall.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="origWrapper">The ProductWrapper.</param>
        /// <param name="overrideLevelId">The level id.</param>
        /// <param name="range">The range to be exported for the element.</param>
        /// <returns>The exported wall handle.</returns>
        public static IFCAnyHandle ExportWallBase(ExporterIFC exporterIFC, Element element, IList<IList<IFCConnectedWallData>> connectedWalls,
            GeometryElement geometryElement, ProductWrapper origWrapper, ElementId overrideLevelId, IFCRange range)
        {
            // Check cases where we choose not to export early.
            ElementId catId = CategoryUtil.GetSafeCategoryId(element);

            Wall wallElement = element as Wall;
            FamilyInstance famInstWallElem = element as FamilyInstance;
            FaceWall faceWall = element as FaceWall;

            bool exportingWallElement = (wallElement != null);
            bool exportingFamilyInstance = (famInstWallElem != null);
            bool exportingFaceWall = (faceWall != null);

            if (!exportingWallElement && !exportingFamilyInstance && !exportingFaceWall)
                return null;

            if (exportingWallElement && IsWallCompletelyClipped(wallElement, exporterIFC, range))
                return null;

            IFCRange zSpan = null;
            double depth = 0.0;
            bool validRange = (range != null && !MathUtil.IsAlmostZero(range.Start - range.End));

            bool exportParts = PartExporter.CanExportParts(element);
            if (exportParts && !PartExporter.CanExportElementInPartExport(element, validRange ? overrideLevelId : element.LevelId, validRange))
                return null;

            IList<Solid> solids = new List<Solid>();
            IList<Mesh> meshes = new List<Mesh>();
            bool exportingInplaceOpenings = false;

            if (!exportParts)
            {
                if (exportingWallElement || exportingFaceWall)
                {
                    GetSolidsAndMeshes(geometryElement, range, ref solids, ref meshes);
                    if (solids.Count == 0 && meshes.Count == 0)
                        return null;
                }
                else
                {
                    GeometryElement geomElemToUse = GetGeometryFromInplaceWall(famInstWallElem);
                    if (geomElemToUse != null)
                    {
                        exportingInplaceOpenings = true;
                    }
                    else
                    {
                        exportingInplaceOpenings = false;
                        geomElemToUse = geometryElement;
                    }
                    Transform trf = Transform.Identity;
                    if (geomElemToUse != geometryElement)
                        trf = famInstWallElem.GetTransform();

                    SolidMeshGeometryInfo solidMeshCapsule = GeometryUtil.GetSplitSolidMeshGeometry(geomElemToUse, trf);
                    solids = solidMeshCapsule.GetSolids();
                    meshes = solidMeshCapsule.GetMeshes();
                }
            }

            IFCFile file = exporterIFC.GetFile();
            using (IFCTransaction tr = new IFCTransaction(file))
            {
                using (ProductWrapper localWrapper = ProductWrapper.Create(origWrapper))
                {
                    // get bounding box height so that we can subtract out pieces properly.
                    // only for Wall, not FamilyInstance.
                    if (exportingWallElement && geometryElement != null)
                    {
                        // There is a problem in the API where some walls with vertical structures are overreporting their height,
                        // making it appear as if there are clipping problems on export.  We will work around this by getting the
                        // height directly from the solid(s).
                        if (solids.Count > 0 && meshes.Count == 0)
                        {
                            zSpan = GetBoundingBoxOfSolids(solids);
                        }
                        else
                        {
                            BoundingBoxXYZ boundingBox = wallElement.get_BoundingBox(null);
                            if (boundingBox != null)
                                zSpan = GetBoundingBoxZRange(boundingBox);
                        }

                        if (zSpan == null)
                            return null;

                        // if we have a top clipping plane, modify depth accordingly.
                        double bottomHeight = validRange ? Math.Max(zSpan.Start, range.Start) : zSpan.Start;
                        double topHeight = validRange ? Math.Min(zSpan.End, range.End) : zSpan.End;
                        depth = topHeight - bottomHeight;
                        if (MathUtil.IsAlmostZero(depth))
                            return null;
                        depth = UnitUtil.ScaleLength(depth);
                    }
                    else
                    {
                        zSpan = new IFCRange();
                    }

                    Document doc = element.Document;

                    double baseWallElevation = 0.0;
                    ElementId baseLevelId = PlacementSetter.GetBaseLevelIdForElement(element);
                    if (baseLevelId != ElementId.InvalidElementId)
                    {
                        Element baseLevel = doc.GetElement(baseLevelId);
                        if (baseLevel is Level)
                            baseWallElevation = (baseLevel as Level).Elevation;
                    }

                    IFCAnyHandle axisRep = null;
                    IFCAnyHandle bodyRep = null;

                    bool exportingAxis = false;
                    Curve trimmedCurve = null;

                    bool exportedAsWallWithAxis = false;
                    bool exportedBodyDirectly = false;

                    Curve centerCurve = GetWallAxis(wallElement);

                    XYZ localXDir = new XYZ(1, 0, 0);
                    XYZ localYDir = new XYZ(0, 1, 0);
                    XYZ localZDir = new XYZ(0, 0, 1);
                    XYZ localOrig = new XYZ(0, 0, 0);
                    double eps = MathUtil.Eps();

                    if (centerCurve != null)
                    {
                        Curve baseCurve = GetWallAxisAtBaseHeight(wallElement);
                        trimmedCurve = GetWallTrimmedCurve(wallElement, baseCurve);

                        IFCRange curveBounds;
                        XYZ oldOrig;
                        GeometryUtil.GetAxisAndRangeFromCurve(trimmedCurve, out curveBounds, out localXDir, out oldOrig);

                        // Move the curve to the bottom of the geometry or the bottom of the range, which is higher.
                        if (baseCurve != null)
                            localOrig = new XYZ(oldOrig.X, oldOrig.Y, validRange ? Math.Max(range.Start, zSpan.Start) : zSpan.Start);
                        else
                            localOrig = oldOrig;

                        double dist = localOrig[2] - oldOrig[2];
                        if (!MathUtil.IsAlmostZero(dist))
                        {
                            XYZ moveVec = new XYZ(0, 0, dist);
                            trimmedCurve = GeometryUtil.MoveCurve(trimmedCurve, moveVec);
                        }
                        localYDir = localZDir.CrossProduct(localXDir);

                        // ensure that X and Z axes are orthogonal.
                        double xzDot = localZDir.DotProduct(localXDir);
                        if (!MathUtil.IsAlmostZero(xzDot))
                            localXDir = localYDir.CrossProduct(localZDir);
                    }
                    else
                    {
                        BoundingBoxXYZ boundingBox = element.get_BoundingBox(null);
                        if (boundingBox != null)
                        {
                            XYZ bBoxMin = boundingBox.Min;
                            XYZ bBoxMax = boundingBox.Max;
                            if (validRange)
                                localOrig = new XYZ(bBoxMin.X, bBoxMin.Y, range.Start);
                            else
                                localOrig = boundingBox.Min;

                            XYZ localXDirMax = null;
                            Transform bTrf = boundingBox.Transform;
                            XYZ localXDirMax1 = new XYZ(bBoxMax.X, localOrig.Y, localOrig.Z);
                            localXDirMax1 = bTrf.OfPoint(localXDirMax1);
                            XYZ localXDirMax2 = new XYZ(localOrig.X, bBoxMax.Y, localOrig.Z);
                            localXDirMax2 = bTrf.OfPoint(localXDirMax2);
                            if (localXDirMax1.DistanceTo(localOrig) >= localXDirMax2.DistanceTo(localOrig))
                                localXDirMax = localXDirMax1;
                            else
                                localXDirMax = localXDirMax2;
                            localXDir = localXDirMax.Subtract(localOrig);
                            localXDir = localXDir.Normalize();
                            localYDir = localZDir.CrossProduct(localXDir);

                            // ensure that X and Z axes are orthogonal.
                            double xzDot = localZDir.DotProduct(localXDir);
                            if (!MathUtil.IsAlmostZero(xzDot))
                                localXDir = localYDir.CrossProduct(localZDir);
                        }
                    }

                    IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle();

                    Transform orientationTrf = Transform.Identity;
                    orientationTrf.BasisX = localXDir;
                    orientationTrf.BasisY = localYDir;
                    orientationTrf.BasisZ = localZDir;
                    orientationTrf.Origin = localOrig;

                    double scaledFootprintArea = 0;
                    double scaledLength = 0;

                    using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element, null, orientationTrf, overrideLevelId))
                    {
                        IFCAnyHandle localPlacement = setter.LocalPlacement;

                        // The local coordinate system of the wall as defined by IFC for IfcWallStandardCase.
                        Plane wallLCS = new Plane(localXDir, localYDir, localOrig);  // project curve to XY plane.
                        XYZ projDir = XYZ.BasisZ;

                        // two representations: axis, body.         
                        {
                            if (!exportParts && (centerCurve != null) && (GeometryUtil.CurveIsLineOrArc(centerCurve)))
                            {
                                exportingAxis = true;

                                string identifierOpt = "Axis";	// IFC2x2 convention
                                string representationTypeOpt = "Curve2D";  // IFC2x2 convention

                                IFCGeometryInfo info = IFCGeometryInfo.CreateCurveGeometryInfo(exporterIFC, wallLCS, projDir, false);
                                ExporterIFCUtils.CollectGeometryInfo(exporterIFC, info, trimmedCurve, XYZ.Zero, true);
                                IList<IFCAnyHandle> axisItems = info.GetCurves();

                                if (axisItems.Count == 0)
                                {
                                    exportingAxis = false;
                                }
                                else
                                {
                                    HashSet<IFCAnyHandle> axisItemSet = new HashSet<IFCAnyHandle>();
                                    foreach (IFCAnyHandle axisItem in axisItems)
                                        axisItemSet.Add(axisItem);

                                    IFCAnyHandle contextOfItemsAxis = exporterIFC.Get3DContextHandle("Axis");
                                    axisRep = RepresentationUtil.CreateShapeRepresentation(exporterIFC, element, catId, contextOfItemsAxis,
                                       identifierOpt, representationTypeOpt, axisItemSet);
                                }
                            }
                        }

                        IList<IFCExtrusionData> cutPairOpenings = new List<IFCExtrusionData>();

                        if (!exportParts && exportingWallElement && exportingAxis && trimmedCurve != null)
                        {
                                    bool isCompletelyClipped;
                            bodyRep = TryToCreateAsExtrusion(exporterIFC, wallElement, connectedWalls, solids, meshes, baseWallElevation,
                                catId, centerCurve, trimmedCurve, wallLCS, depth, zSpan, range, setter,
                                        out cutPairOpenings, out isCompletelyClipped, out scaledFootprintArea, out scaledLength);
                                    if (isCompletelyClipped)
                                        return null;
                                    if (!IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep))
                                        exportedAsWallWithAxis = true;
                                }

                        using (IFCExtrusionCreationData extraParams = new IFCExtrusionCreationData())
                        {
                            BodyData bodyData = null;

                            if (!exportedAsWallWithAxis)
                            {
                                extraParams.PossibleExtrusionAxes = IFCExtrusionAxes.TryZ;   // only allow vertical extrusions!
                                extraParams.AreInnerRegionsOpenings = true;

                                BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true);
                                
                                // Swept solids are not natively exported as part of CV2.0.  
                                // We have removed the UI toggle for this, so that it is by default false, but keep for possible future use.
                                if (ExporterCacheManager.ExportOptionsCache.ExportAdvancedSweptSolids)
                                    bodyExporterOptions.TryToExportAsSweptSolid = true;

                                ElementId overrideMaterialId = ElementId.InvalidElementId;
                                if (exportingWallElement)
                                    overrideMaterialId = HostObjectExporter.GetFirstLayerMaterialId(wallElement);

                                if (!exportParts)
                                {
                                    if ((solids.Count > 0) || (meshes.Count > 0))
                                    {
                                        bodyRep = BodyExporter.ExportBody(exporterIFC, element, catId, overrideMaterialId,
                                            solids, meshes, bodyExporterOptions, extraParams).RepresentationHnd;
                                    }
                                    else
                                    {
                                        IList<GeometryObject> geomElemList = new List<GeometryObject>();
                                        geomElemList.Add(geometryElement);
                                        bodyData = BodyExporter.ExportBody(exporterIFC, element, catId, overrideMaterialId,
                                            geomElemList, bodyExporterOptions, extraParams);
                                        bodyRep = bodyData.RepresentationHnd;
                                    }

                                    if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep))
                                    {
                                        extraParams.ClearOpenings();
                                        return null;
                                    }
                                }

                                // We will be able to export as a IfcWallStandardCase as long as we have an axis curve.
                                XYZ extrDirUsed = XYZ.Zero;
                                if (extraParams.HasExtrusionDirection)
                                {
                                    extrDirUsed = extraParams.ExtrusionDirection;
                                    if (MathUtil.IsAlmostEqual(Math.Abs(extrDirUsed[2]), 1.0))
                                    {
                                        if ((solids.Count == 1) && (meshes.Count == 0))
                                            exportedAsWallWithAxis = exportingAxis;
                                        exportedBodyDirectly = true;
                                    }
                                }
                            }

                            IFCAnyHandle prodRep = null;
                            if (!exportParts)
                            {
                                IList<IFCAnyHandle> representations = new List<IFCAnyHandle>();
                                if (exportingAxis)
                                    representations.Add(axisRep);

                                representations.Add(bodyRep);

                                IFCAnyHandle boundingBoxRep = null;
                                if ((solids.Count > 0) || (meshes.Count > 0))
                                    boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, solids, meshes, Transform.Identity);
                                else
                                    boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, geometryElement, Transform.Identity);

                                if (boundingBoxRep != null)
                                    representations.Add(boundingBoxRep);

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

                            ElementId matId = ElementId.InvalidElementId;
                            string objectType = NamingUtil.CreateIFCObjectName(exporterIFC, element);
                            IFCAnyHandle wallHnd = null;

                            string elemGUID = null;
                            int subElementIndex = ExporterStateManager.GetCurrentRangeIndex();
                            if (subElementIndex == 0)
                                elemGUID = GUIDUtil.CreateGUID(element);
                            else if (subElementIndex <= ExporterStateManager.RangeIndexSetter.GetMaxStableGUIDs())
                                elemGUID = GUIDUtil.CreateSubElementGUID(element, subElementIndex + (int)IFCGenericSubElements.SplitInstanceStart - 1);
                            else
                                elemGUID = GUIDUtil.CreateGUID();
                            
                            string elemName = NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element));
                            string elemDesc = NamingUtil.GetDescriptionOverride(element, null);
                            string elemObjectType = NamingUtil.GetObjectTypeOverride(element, objectType);
                            string elemTag = NamingUtil.GetTagOverride(element, NamingUtil.CreateIFCElementId(element));

                            string ifcType = IFCValidateEntry.GetValidIFCType(element, null);

                            // For Foundation and Retaining walls, allow exporting as IfcFooting instead.
                            bool exportAsFooting = false;
                            if (exportingWallElement)
                            {
                                WallType wallType = wallElement.WallType;

                                if (wallType != null)
                                {
                                    int wallFunction;
                                    if (ParameterUtil.GetIntValueFromElement(wallType, BuiltInParameter.FUNCTION_PARAM, out wallFunction) != null)
                                    {
                                        if (wallFunction == (int)WallFunction.Retaining || wallFunction == (int)WallFunction.Foundation)
                                        {
                                            // In this case, allow potential to export foundation and retaining walls as footing.
                                            string enumTypeValue = null;
                                            IFCExportType exportType = ExporterUtil.GetExportType(exporterIFC, wallElement, out enumTypeValue);
                                            if (exportType == IFCExportType.IfcFooting)
                                                exportAsFooting = true;
                                        }
                                    }
                                }
                            }

                            if (exportedAsWallWithAxis)
                            {
                                if (exportAsFooting)
                                {
                                    wallHnd = IFCInstanceExporter.CreateFooting(file, elemGUID, ownerHistory, elemName, elemDesc, elemObjectType,
                                        localPlacement, exportParts ? null : prodRep, elemTag, ifcType);
                                }
                                else
                                {
                                    bool exportAsWall = exportParts;
                                    if (!exportAsWall)
                                    {
                                        // (For Reference View export) If the representation returned earlier is of type Tessellation, create IfcWall instead.
                                        foreach (IFCAnyHandle pRep in IFCAnyHandleUtil.GetRepresentations(prodRep))
                                        {
                                            if (String.Compare(IFCAnyHandleUtil.GetRepresentationType(pRep), "Tessellation") == 0)
                                            {
                                                exportAsWall = true;
                                                break;
                                            }
                                        }
                                    }

                                    if (exportAsWall)
                                    {
                                        wallHnd = IFCInstanceExporter.CreateWall(file, elemGUID, ownerHistory, elemName, elemDesc, elemObjectType,
                                                localPlacement, null, elemTag, ifcType);
                                    }
                                    else
                                    {
                                        wallHnd = IFCInstanceExporter.CreateWallStandardCase(file, elemGUID, ownerHistory, elemName, elemDesc, elemObjectType,
                                            localPlacement, prodRep, elemTag, ifcType);
                                    }
                                }

                                if (exportParts)
                                    PartExporter.ExportHostPart(exporterIFC, element, wallHnd, localWrapper, setter, localPlacement, overrideLevelId);

                                localWrapper.AddElement(element, wallHnd, setter, extraParams, true);

                                if (!exportParts)
                                {
                                    OpeningUtil.CreateOpeningsIfNecessary(wallHnd, element, cutPairOpenings, null,
                                        exporterIFC, localPlacement, setter, localWrapper);
                                    if (exportedBodyDirectly)
                                    {
                                        Transform offsetTransform = (bodyData != null) ? bodyData.OffsetTransform : Transform.Identity;
                                        OpeningUtil.CreateOpeningsIfNecessary(wallHnd, element, extraParams, offsetTransform,
                                            exporterIFC, localPlacement, setter, localWrapper);
                                    }
                                    else
                                    {
                                        double scaledWidth = UnitUtil.ScaleLength(wallElement.Width);
                                        OpeningUtil.AddOpeningsToElement(exporterIFC, wallHnd, wallElement, null, scaledWidth, range, setter, localPlacement, localWrapper);
                                    }
                                }

                                // export Base Quantities
                                if (ExporterCacheManager.ExportOptionsCache.ExportBaseQuantities)
                                {
                                    scaledFootprintArea = MathUtil.AreaIsAlmostZero(scaledFootprintArea) ? extraParams.ScaledArea : scaledFootprintArea;
                                    scaledLength = MathUtil.IsAlmostZero(scaledLength) ? extraParams.ScaledLength : scaledLength;
                                    PropertyUtil.CreateWallBaseQuantities(exporterIFC, wallElement, solids, meshes, wallHnd, scaledLength, depth, scaledFootprintArea);
                                }
                            }
                            else
                            {
                                if (exportAsFooting)
                                {
                                    wallHnd = IFCInstanceExporter.CreateFooting(file, elemGUID, ownerHistory, elemName, elemDesc, elemObjectType,
                                        localPlacement, exportParts ? null : prodRep, elemTag, ifcType);
                                }
                                else
                                {
                                    wallHnd = IFCInstanceExporter.CreateWall(file, elemGUID, ownerHistory, elemName, elemDesc, elemObjectType,
                                        localPlacement, exportParts ? null : prodRep, elemTag, ifcType);
                                }

                                if (exportParts)
                                    PartExporter.ExportHostPart(exporterIFC, element, wallHnd, localWrapper, setter, localPlacement, overrideLevelId);

                                localWrapper.AddElement(element, wallHnd, setter, extraParams, true);

                                if (!exportParts)
                                {
                                    // Only export one material for 2x2; for future versions, export the whole list.
                                    if (ExporterCacheManager.ExportOptionsCache.ExportAs2x2 || exportingFamilyInstance)
                                    {
                                        matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(solids, meshes, element);
                                        if (matId != ElementId.InvalidElementId)
                                            CategoryUtil.CreateMaterialAssociation(exporterIFC, wallHnd, matId);
                                    }

                                    if (exportingInplaceOpenings)
                                    {
                                        OpeningUtil.AddOpeningsToElement(exporterIFC, wallHnd, famInstWallElem, null, 0.0, range, setter, localPlacement, localWrapper);
                                    }

                                    if (exportedBodyDirectly)
                                    {
                                        Transform offsetTransform = (bodyData != null) ? bodyData.OffsetTransform : Transform.Identity;
                                        OpeningUtil.CreateOpeningsIfNecessary(wallHnd, element, extraParams, offsetTransform,
                                            exporterIFC, localPlacement, setter, localWrapper);
                                    }
                                }
                            }

                            ElementId wallLevelId = (validRange) ? setter.LevelId : ElementId.InvalidElementId;

                            if ((exportingWallElement || exportingFaceWall) && !exportParts)
                            {
                                HostObject hostObject = null;
                                if (exportingWallElement)
                                    hostObject = wallElement;
                                else
                                    hostObject = faceWall;
                                if (!ExporterCacheManager.ExportOptionsCache.ExportAs2x2 || exportedAsWallWithAxis)
                                    HostObjectExporter.ExportHostObjectMaterials(exporterIFC, hostObject, localWrapper.GetAnElement(),
                                        geometryElement, localWrapper, wallLevelId, Toolkit.IFCLayerSetDirection.Axis2, !exportedAsWallWithAxis);
                            }

                            ExportWallType(exporterIFC, localWrapper, wallHnd, element, matId, exportedAsWallWithAxis, exportAsFooting);

                            SpaceBoundingElementUtil.RegisterSpaceBoundingElementHandle(exporterIFC, wallHnd, element.Id, wallLevelId);

                            tr.Commit();
                            return wallHnd;
                        }
                    }
                }
            }
        }
Пример #10
0
        /// <summary>
        /// Exports a beam to IFC beam.
        /// </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 ExportBeam(ExporterIFC exporterIFC,
                                      Element element, GeometryElement geometryElement, ProductWrapper productWrapper)
        {
            if (geometryElement == null)
            {
                return;
            }

            IFCFile file = exporterIFC.GetFile();

            using (IFCTransaction transaction = new IFCTransaction(file))
            {
                LocationCurve locCurve  = element.Location as LocationCurve;
                Transform     orientTrf = Transform.Identity;

                bool         canExportAxis = (locCurve != null);
                IFCAnyHandle axisRep       = null;

                XYZ   beamDirection = null;
                XYZ   projDir       = null;
                Curve curve         = null;

                Plane plane = null;
                if (canExportAxis)
                {
                    curve = locCurve.Curve;
                    if (curve is Line)
                    {
                        Line line = curve as Line;
                        XYZ  planeY, planeOrig;
                        planeOrig     = line.GetEndPoint(0);
                        beamDirection = line.Direction;
                        if (Math.Abs(beamDirection.Z) < 0.707)  // approx 1.0/sqrt(2.0)
                        {
                            planeY = XYZ.BasisZ.CrossProduct(beamDirection);
                        }
                        else
                        {
                            planeY = XYZ.BasisX.CrossProduct(beamDirection);
                        }
                        planeY           = planeY.Normalize();
                        projDir          = beamDirection.CrossProduct(planeY);
                        plane            = new Plane(beamDirection, planeY, planeOrig);
                        orientTrf.BasisX = beamDirection; orientTrf.BasisY = planeY; orientTrf.BasisZ = projDir; orientTrf.Origin = planeOrig;
                    }
                    else if (curve is Arc)
                    {
                        XYZ yDir, center;
                        Arc arc = curve as Arc;
                        beamDirection    = arc.XDirection; yDir = arc.YDirection; projDir = arc.Normal; center = arc.Center;
                        plane            = new Plane(beamDirection, yDir, center);
                        orientTrf.BasisX = beamDirection; orientTrf.BasisY = yDir; orientTrf.BasisZ = projDir; orientTrf.Origin = center;
                    }
                    else
                    {
                        canExportAxis = false;
                    }
                }

                using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element, null, canExportAxis ? orientTrf : null))
                {
                    IFCAnyHandle          localPlacement = setter.LocalPlacement;
                    SolidMeshGeometryInfo solidMeshInfo  = GeometryUtil.GetSplitSolidMeshGeometry(geometryElement);

                    using (IFCExtrusionCreationData extrusionCreationData = new IFCExtrusionCreationData())
                    {
                        extrusionCreationData.SetLocalPlacement(localPlacement);
                        if (canExportAxis && (orientTrf.BasisX != null))
                        {
                            extrusionCreationData.CustomAxis            = beamDirection;
                            extrusionCreationData.PossibleExtrusionAxes = IFCExtrusionAxes.TryCustom;
                        }
                        else
                        {
                            extrusionCreationData.PossibleExtrusionAxes = IFCExtrusionAxes.TryXY;
                        }

                        IList <Solid> solids = solidMeshInfo.GetSolids();
                        IList <Mesh>  meshes = solidMeshInfo.GetMeshes();

                        ElementId catId = CategoryUtil.GetSafeCategoryId(element);

                        // The representation handle generated from one of the methods below.
                        IFCAnyHandle repHnd = null;

                        // The list of materials in the solids or meshes.
                        ICollection <ElementId> materialIds = new HashSet <ElementId>();

                        // There may be an offset to make the local coordinate system
                        // be near the origin.  This offset will be used to move the axis to the new LCS.
                        Transform offsetTransform = null;

                        // If we have a beam with a Linear location line that only has one solid geometry,
                        // we will try to use the ExtrusionAnalyzer to generate an extrusion with 0 or more clippings.
                        // This code is currently limited in that it will not process beams with openings, so we
                        // use other methods below if this one fails.
                        if (solids.Count == 1 && meshes.Count == 0 && (canExportAxis && (curve is Line)))
                        {
                            bool completelyClipped;
                            beamDirection = orientTrf.BasisX;
                            Plane beamExtrusionPlane = new Plane(orientTrf.BasisY, orientTrf.BasisZ, orientTrf.Origin);
                            repHnd = ExtrusionExporter.CreateExtrusionWithClipping(exporterIFC, element,
                                                                                   catId, solids[0], beamExtrusionPlane, beamDirection, null, out completelyClipped);
                            if (completelyClipped)
                            {
                                return;
                            }

                            if (!IFCAnyHandleUtil.IsNullOrHasNoValue(repHnd))
                            {
                                // This is used by the BeamSlopeCalculator.  This should probably be generated automatically by
                                // CreateExtrusionWithClipping.
                                IFCExtrusionBasis bestAxis = (Math.Abs(beamDirection[0]) > Math.Abs(beamDirection[1])) ?
                                                             IFCExtrusionBasis.BasisX : IFCExtrusionBasis.BasisY;
                                extrusionCreationData.Slope = GeometryUtil.GetSimpleExtrusionSlope(beamDirection, bestAxis);
                                ElementId materialId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(solids[0], exporterIFC, element);
                                if (materialId != ElementId.InvalidElementId)
                                {
                                    materialIds.Add(materialId);
                                }
                            }
                        }

                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(repHnd))
                        {
                            BodyData bodyData = null;

                            BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true);
                            if (solids.Count > 0 || meshes.Count > 0)
                            {
                                bodyData = BodyExporter.ExportBody(exporterIFC, element, catId, ElementId.InvalidElementId,
                                                                   solids, meshes, bodyExporterOptions, extrusionCreationData);
                            }
                            else
                            {
                                IList <GeometryObject> geomlist = new List <GeometryObject>();
                                geomlist.Add(geometryElement);
                                bodyData = BodyExporter.ExportBody(exporterIFC, element, catId, ElementId.InvalidElementId,
                                                                   geomlist, bodyExporterOptions, extrusionCreationData);
                            }
                            repHnd          = bodyData.RepresentationHnd;
                            materialIds     = bodyData.MaterialIds;
                            offsetTransform = bodyData.OffsetTransform;
                        }

                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(repHnd))
                        {
                            extrusionCreationData.ClearOpenings();
                            return;
                        }

                        IList <IFCAnyHandle> representations = new List <IFCAnyHandle>();

                        if (canExportAxis)
                        {
                            XYZ curveOffset = new XYZ(0, 0, 0);
                            if (offsetTransform != null)
                            {
                                curveOffset = -UnitUtil.UnscaleLength(offsetTransform.Origin);
                            }
                            else
                            {
                                // Note that we do not have to have any scaling adjustment here, since the curve origin is in the
                                // same internal coordinate system as the curve.
                                curveOffset = -plane.Origin;
                            }

                            Plane           offsetPlane = new Plane(plane.XVec, plane.YVec, XYZ.Zero);
                            IFCGeometryInfo info        = IFCGeometryInfo.CreateCurveGeometryInfo(exporterIFC, offsetPlane, projDir, false);
                            ExporterIFCUtils.CollectGeometryInfo(exporterIFC, info, curve, curveOffset, true);

                            IList <IFCAnyHandle> axis_items = info.GetCurves();

                            if (axis_items.Count > 0)
                            {
                                string identifierOpt         = "Axis";    // this is by IFC2x2 convention, not temporary
                                string representationTypeOpt = "Curve2D"; // this is by IFC2x2 convention, not temporary
                                axisRep = RepresentationUtil.CreateShapeRepresentation(exporterIFC, element, catId, exporterIFC.Get3DContextHandle(identifierOpt),
                                                                                       identifierOpt, representationTypeOpt, axis_items);
                                representations.Add(axisRep);
                            }
                        }
                        representations.Add(repHnd);

                        Transform    boundingBoxTrf = (offsetTransform == null) ? Transform.Identity : offsetTransform.Inverse;
                        IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, geometryElement, boundingBoxTrf);
                        if (boundingBoxRep != null)
                        {
                            representations.Add(boundingBoxRep);
                        }

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

                        string instanceGUID        = GUIDUtil.CreateGUID(element);
                        string instanceName        = NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element));
                        string instanceDescription = NamingUtil.GetDescriptionOverride(element, null);
                        string instanceObjectType  = NamingUtil.GetObjectTypeOverride(element, NamingUtil.CreateIFCObjectName(exporterIFC, element));
                        string instanceTag         = NamingUtil.GetTagOverride(element, NamingUtil.CreateIFCElementId(element));
                        string preDefinedType      = "BEAM"; // Default predefined type for Beam
                        preDefinedType = IFCValidateEntry.GetValidIFCType(element, preDefinedType);

                        IFCAnyHandle beam = IFCInstanceExporter.CreateBeam(file, instanceGUID, exporterIFC.GetOwnerHistoryHandle(),
                                                                           instanceName, instanceDescription, instanceObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, instanceTag, preDefinedType);

                        productWrapper.AddElement(element, beam, setter, extrusionCreationData, true);

                        OpeningUtil.CreateOpeningsIfNecessary(beam, element, extrusionCreationData, offsetTransform, exporterIFC,
                                                              extrusionCreationData.GetLocalPlacement(), setter, productWrapper);

                        FamilyTypeInfo typeInfo = new FamilyTypeInfo();
                        typeInfo.ScaledDepth          = extrusionCreationData.ScaledLength;
                        typeInfo.ScaledArea           = extrusionCreationData.ScaledArea;
                        typeInfo.ScaledInnerPerimeter = extrusionCreationData.ScaledInnerPerimeter;
                        typeInfo.ScaledOuterPerimeter = extrusionCreationData.ScaledOuterPerimeter;
                        PropertyUtil.CreateBeamColumnBaseQuantities(exporterIFC, beam, element, typeInfo, null);

                        if (materialIds.Count != 0)
                        {
                            CategoryUtil.CreateMaterialAssociations(exporterIFC, beam, materialIds);
                        }

                        // Register the beam's IFC handle for later use by truss and beam system export.
                        ExporterCacheManager.ElementToHandleCache.Register(element.Id, beam);
                    }
                }

                transaction.Commit();
            }
        }
Пример #11
0
        /// <summary>
        /// Returns a handle for creation of an AdvancedBrep with AdvancedFace and assigns it to the file
        /// </summary>
        /// <param name="exporterIFC">exporter IFC</param>
        /// <param name="element">the element</param>
        /// <param name="options">exporter option</param>
        /// <param name="geomObject">the geometry object</param>
        /// <returns>the handle</returns>
        public static IFCAnyHandle ExportBodyAsAdvancedBrep(ExporterIFC exporterIFC, Element element, BodyExporterOptions options,
            GeometryObject geomObject)
        {
            IFCFile file = exporterIFC.GetFile();
            Document document = element.Document;

            // IFCFuzzyXYZ will be used in this routine to compare 2 XYZs, we consider two points are the same if their distance
            // is within this tolerance
            IFCFuzzyXYZ.IFCFuzzyXYZEpsilon = document.Application.VertexTolerance; 
            
            IFCAnyHandle advancedBrep = null;

         using (IFCTransaction tr = new IFCTransaction(file))
         {
            try
            {
                if (!(geomObject is Solid))
                {
                    return null;
                }
                HashSet<IFCAnyHandle> cfsFaces = new HashSet<IFCAnyHandle>();
                Solid geomSolid = geomObject as Solid;
                FaceArray faces = geomSolid.Faces;

               // Check for supported curve and face types before creating an advanced BRep.
               IList<KeyValuePair<Edge, Curve>> edgesAndCurves = new List<KeyValuePair<Edge, Curve>>();
                foreach (Edge edge in geomSolid.Edges) 
                {
                    Curve currCurve = edge.AsCurve();
                  if (currCurve == null)
                     return null;

                  bool isValidCurve = !(currCurve is CylindricalHelix);
                    if (!isValidCurve)
                        return null;

                    // based on the definition of IfcAdvancedBrep in IFC 4 specification, an IfcAdvancedBrep must contain a closed shell, so we
                    // have a test to reject all open shells here.
                    // we check that geomSolid is an actual solid and not an open shell by verifying that each edge is shared by exactly 2 faces.
                    for (int ii = 0; ii < 2; ii++)
                    {
                        if (edge.GetFace(ii) == null)
                            return null;
                        }

                  edgesAndCurves.Add(new KeyValuePair<Edge, Curve>(edge, currCurve));
                }

                foreach (Face face in geomSolid.Faces) 
                {
                  bool isValidFace = (face is PlanarFace) || (face is CylindricalFace) || (face is RuledFace) || (face is HermiteFace) || (face is RevolvedFace) || (face is ConicalFace);
                    if (!isValidFace) 
                    {
                        return null;
                    }
                }

                Dictionary<Face, IList<Edge>> faceToEdges = new Dictionary<Face, IList<Edge>>();
                Dictionary<Edge, IFCAnyHandle> edgeToIfcEdgeCurve = new Dictionary<Edge, IFCAnyHandle>();

               // A map of already created IfcCartesianPoints, to avoid duplication.  This is used for vertex points and other geometry in the BRep.
               // We do not share IfcCartesianPoints across BReps.
               IDictionary<IFCFuzzyXYZ, IFCAnyHandle> cartesianPoints = new SortedDictionary<IFCFuzzyXYZ, IFCAnyHandle>();

               // A map of already created IfcVertexPoints, to avoid duplication.
                IDictionary<IFCFuzzyXYZ, IFCAnyHandle> vertices = new SortedDictionary<IFCFuzzyXYZ, IFCAnyHandle>();

                // First phase: get all the vertices:
               foreach (KeyValuePair<Edge, Curve> edgeAndCurve in edgesAndCurves)
                {
                  Edge edge = edgeAndCurve.Key;
                  Curve currCurve = edgeAndCurve.Value;

                    XYZ startPoint = currCurve.GetEndPoint(0);
                    XYZ endPoint = currCurve.GetEndPoint(1);
                    IFCFuzzyXYZ fuzzyStartPoint = new IFCFuzzyXYZ(startPoint);
                    IFCFuzzyXYZ fuzzyEndPoint = new IFCFuzzyXYZ(endPoint);
                    IFCAnyHandle edgeStart = null;
                    IFCAnyHandle edgeEnd = null;

                    if (vertices.ContainsKey(fuzzyStartPoint))
                    {
                        edgeStart = vertices[fuzzyStartPoint];
                    }
                    else
                    {
                     IFCAnyHandle edgeStartCP = GeometryUtil.XYZtoIfcCartesianPoint(exporterIFC, currCurve.GetEndPoint(0), cartesianPoints);
                        edgeStart = IFCInstanceExporter.CreateVertexPoint(file, edgeStartCP);
                        vertices.Add(fuzzyStartPoint, edgeStart);
                    }

                    if (vertices.ContainsKey(fuzzyEndPoint))
                    {
                        edgeEnd = vertices[fuzzyEndPoint];
                    }
                    else
                    {
                     IFCAnyHandle edgeEndCP = GeometryUtil.XYZtoIfcCartesianPoint(exporterIFC, currCurve.GetEndPoint(1), cartesianPoints);
                        edgeEnd = IFCInstanceExporter.CreateVertexPoint(file, edgeEndCP);
                        vertices.Add(fuzzyEndPoint, edgeEnd);
                    }

                  IFCAnyHandle edgeCurve = CreateEdgeCurveFromCurve(file, exporterIFC, currCurve, edgeStart, edgeEnd, true, cartesianPoints);

                    edgeToIfcEdgeCurve.Add(edge, edgeCurve);

                    Face face = null;
                    for (int ii = 0; ii < 2; ii++)
                    {
                        face = edge.GetFace(ii);
                        if (!faceToEdges.ContainsKey(face))
                        {
                            faceToEdges.Add(face, new List<Edge>());
                        }
                        IList<Edge> edges = faceToEdges[face];
                        edges.Add(edge);
                    }
                }

                // Second phase: create IfcFaceOuterBound, IfcFaceInnerBound, IfcAdvancedFace and IfcAdvancedBrep
               foreach (Face face in geomSolid.Faces)
               {
                  // List of created IfcEdgeLoops of this face
                  IList<IFCAnyHandle> edgeLoopList = new List<IFCAnyHandle>();
                  // List of created IfcOrientedEdge in one loop
                  IList<IFCAnyHandle> orientedEdgeList = new List<IFCAnyHandle>();
                  IFCAnyHandle surface = null;
                  IList<HashSet<IFCAnyHandle>> boundsCollection = new List<HashSet<IFCAnyHandle>>();

                  // calculate sameSense by getting a point on the surface and compute the normal of the face and the surface at that point
                  // if these two vectors agree, then sameSense is true.
                  // The point we use to test will be the start point of the first edge in the first loop of this face
                  bool sameSenseAF = true;
                  EdgeArrayArray faceEdgeLoops = face.EdgeLoops;
                  if (faceEdgeLoops == null || faceEdgeLoops.Size == 0)
                  {
                     return null;
                  }
                  EdgeArray firstEdgeLoop = faceEdgeLoops.get_Item(0);
                  if (firstEdgeLoop == null)
                  {
                     return null;
                  }
                  Edge firstEdge = firstEdgeLoop.get_Item(0);
                  UV pointToTest = firstEdge.EvaluateOnFace(0, face);
                  // Compute the normal of the FACE at pointToTest
                  XYZ faceNormal = face.ComputeNormal(pointToTest);
                  // Compute the normal of the SURFACE at pointToTest
                  Transform testPointDerivatives = face.ComputeDerivatives(pointToTest);
                  XYZ surfaceNormal = testPointDerivatives.BasisZ;
                  if (!faceNormal.IsAlmostEqualTo(surfaceNormal))
                  {
                     sameSenseAF = false;
                  }

                  Dictionary<EdgeArray, IList<EdgeArray>> sortedEdgeLoop = GeometryUtil.SortEdgeLoop(faceEdgeLoops, face);
                  // check that we get back the same number of edgeloop
                  int numberOfSortedEdgeLoop = 0;
                  foreach (KeyValuePair<EdgeArray, IList<EdgeArray>> pair in sortedEdgeLoop)
                  {
                     numberOfSortedEdgeLoop += 1 + pair.Value.Count;
                  }

                  if (numberOfSortedEdgeLoop != face.EdgeLoops.Size)
                  {
                     return null;
                  }

                  foreach (KeyValuePair<EdgeArray, IList<EdgeArray>> pair in sortedEdgeLoop)
                  {
                     if (pair.Key == null || pair.Value == null)
                        return null;

                     HashSet<IFCAnyHandle> bounds = new HashSet<IFCAnyHandle>();

                     // Append the outerloop at the beginning of the list of inner loop
                     pair.Value.Insert(0, pair.Key);

                     // Process each inner loop
                     foreach (EdgeArray edgeArray in pair.Value)
                     {
                        // Map each edge in this loop back to its corresponding edge curve and then calculate its orientation to create IfcOrientedEdge
                        foreach (Edge edge in edgeArray)
                        {
                           // The reason why edgeToIfcEdgeCurve cannot find edge is that either we haven't created the IfcOrientedEdge
                           // corresponding to that edge OR we already have but the dictionary cannot find the edge as its key because 
                           // Face.EdgeLoop and geomSolid.Edges return different pointers for the same edge. This can be avoided if 
                           // Equals() method is implemented for Edge
                           if (!edgeToIfcEdgeCurve.ContainsKey(edge))
                              return null;

                           IFCAnyHandle edgeCurve = edgeToIfcEdgeCurve[edge];

                           Curve currCurve = edge.AsCurve();
                           Curve curveInCurrentFace = edge.AsCurveFollowingFace(face);

                           if (currCurve == null || curveInCurrentFace == null)
                              return null;

                           // if the curve length is 0, ignore it.
                           if (MathUtil.IsAlmostZero(currCurve.ApproximateLength))
                              continue;

                           // if the curve is unbound, it means that the solid may be corrupted, we shouldn't process it anymore
                           if (!currCurve.IsBound)
                              return null;

                           bool orientation = currCurve.GetEndPoint(0).IsAlmostEqualTo(curveInCurrentFace.GetEndPoint(0));

                           IFCAnyHandle orientedEdge = IFCInstanceExporter.CreateOrientedEdge(file, edgeCurve, orientation);
                           orientedEdgeList.Add(orientedEdge);
                        }

                        IFCAnyHandle edgeLoop = IFCInstanceExporter.CreateEdgeLoop(file, orientedEdgeList);
                        edgeLoopList.Add(edgeLoop);

                        IFCAnyHandle faceBound = null;

                        // EdgeLoopList has only 1 element indicates that this is the outer loop
                        if (edgeLoopList.Count == 1)
                           faceBound = IFCInstanceExporter.CreateFaceOuterBound(file, edgeLoop, true);
                        else
                           faceBound = IFCInstanceExporter.CreateFaceBound(file, edgeLoop, false);

                        bounds.Add(faceBound);

                        // After finishing processing one loop, clear orientedEdgeList
                        orientedEdgeList.Clear();
                     }
                     boundsCollection.Add(bounds);
                  }

                  edgeLoopList.Clear();

                  // TODO: create a new face processing method to factor out this code
                  // process the face now
                  if (face is PlanarFace)
                  {
                     PlanarFace plFace = face as PlanarFace;
                     IFCAnyHandle location = GeometryUtil.XYZtoIfcCartesianPoint(exporterIFC, plFace.Origin, cartesianPoints);

                     // Since there is no easy way to get the surface normal, we will calculate the face's normal and negate it if we know
                     // the surface normal doesn't agree with the face normal based on the sameSense attribute that we calculate above
                     XYZ zdir = plFace.FaceNormal;
                     if (!sameSenseAF)
                        zdir = zdir.Negate();
                     XYZ xdir = plFace.XVector;

                     IFCAnyHandle position = CreatePositionForFace(exporterIFC, location, zdir, xdir);

                     surface = IFCInstanceExporter.CreatePlane(file, position);
                  }
                  else if (face is CylindricalFace)
                  {
                     CylindricalFace cylFace = face as CylindricalFace;
                     IFCAnyHandle location = GeometryUtil.XYZtoIfcCartesianPoint(exporterIFC, cylFace.Origin, cartesianPoints);

                     // get radius-x and radius-y and the position of the origin
                     XYZ rad = UnitUtil.ScaleLength(cylFace.get_Radius(0));
                     double radius = rad.GetLength();

                     XYZ zdir = cylFace.Axis;
                     XYZ xdir = rad.Normalize();

                     IFCAnyHandle position = CreatePositionForFace(exporterIFC, location, zdir, xdir);

                     surface = IFCInstanceExporter.CreateCylindricalSurface(file, position, radius);
                  }
                  else if (face is ConicalFace)
                  {
                     ConicalFace conicalFace = face as ConicalFace;
                     IFCAnyHandle location = GeometryUtil.XYZtoIfcCartesianPoint(exporterIFC, conicalFace.Origin, cartesianPoints);

                     XYZ zdir = conicalFace.Axis;
                     if (zdir == null)
                        return null;

                     // Create a finite profile curve for the cone based on the bounding box.
                     BoundingBoxUV coneUV = conicalFace.GetBoundingBox();
                     if (coneUV == null)
                        return null;

                     XYZ startPoint = conicalFace.Evaluate(new UV(0, coneUV.Min.V));
                     XYZ endPoint = conicalFace.Evaluate(new UV(0, coneUV.Max.V));

                     Curve profileCurve = Line.CreateBound(startPoint, endPoint);

                     IFCAnyHandle axis = GeometryUtil.VectorToIfcDirection(exporterIFC, zdir);

                     IFCAnyHandle axisPosition = IFCInstanceExporter.CreateAxis1Placement(file, location, axis);

                     IFCAnyHandle sweptCurve = CreateProfileCurveFromCurve(file, exporterIFC, profileCurve, Resources.ConicalFaceProfileCurve, cartesianPoints);

                     // The profile position is optional in IFC4+.
                     surface = IFCInstanceExporter.CreateSurfaceOfRevolution(file, sweptCurve, null, axisPosition);
                  }
                  else if (face is RevolvedFace)
                  {
                     RevolvedFace revFace = face as RevolvedFace;
                     IFCAnyHandle location = GeometryUtil.XYZtoIfcCartesianPoint(exporterIFC, revFace.Origin, cartesianPoints);

                     XYZ zdir = revFace.Axis;
                     if (zdir == null)
                        return null;

                     // Note that the returned curve is in the coordinate system of the face.
                     Curve curve = revFace.Curve;
                     if (curve == null)
                        return null;

                     // Create arbitrary plane with z direction as normal.
                     Plane arbitraryPlane = new Plane(zdir, XYZ.Zero);

                     Transform revitTransform = Transform.Identity;
                     revitTransform.BasisX = arbitraryPlane.XVec;
                     revitTransform.BasisY = arbitraryPlane.YVec;
                     revitTransform.BasisZ = zdir;
                     revitTransform.Origin = revFace.Origin;
                     Curve profileCurve = curve.CreateTransformed(revitTransform);

                     IFCAnyHandle axis = GeometryUtil.VectorToIfcDirection(exporterIFC, zdir);

                     IFCAnyHandle axisPosition = IFCInstanceExporter.CreateAxis1Placement(file, location, axis);

                     IFCAnyHandle sweptCurve = CreateProfileCurveFromCurve(file, exporterIFC, profileCurve, Resources.RevolvedFaceProfileCurve, cartesianPoints);

                     // The profile position is optional in IFC4+.
                     surface = IFCInstanceExporter.CreateSurfaceOfRevolution(file, sweptCurve, null, axisPosition);
                  }
                  else if (face is RuledFace)
                  {
                     return null;        // currently does not support this type of face
                  }
                  else if (face is HermiteFace)
                  {
                     return null;        // currently does not support this type of face
                  }
                  else
                  {
                     return null;
                  }

                  // If we had trouble creating a surface, stop trying.
                  if (IFCAnyHandleUtil.IsNullOrHasNoValue(surface))
                     return null;

                  foreach (HashSet<IFCAnyHandle> faceBound in boundsCollection)
                  {
                     IFCAnyHandle advancedFace = IFCInstanceExporter.CreateAdvancedFace(file, faceBound, surface, sameSenseAF);
                     cfsFaces.Add(advancedFace);
                  }
               }

                // create advancedBrep
                IFCAnyHandle closedShell = IFCInstanceExporter.CreateClosedShell(file, cfsFaces);
                advancedBrep = IFCInstanceExporter.CreateAdvancedBrep(file, closedShell);

               if (IFCAnyHandleUtil.IsNullOrHasNoValue(advancedBrep))
                  tr.RollBack();
               else
                  tr.Commit();

                return advancedBrep;
            }
            catch
            {
                return null;
            }
        }
      }
        /// <summary>
        /// Exports a CeilingAndFloor element to IFC.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="floor">The floor element.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        public static void ExportCeilingAndFloorElement(ExporterIFC exporterIFC, CeilingAndFloor floorElement, GeometryElement geometryElement, 
            ProductWrapper productWrapper)
        {
            if (geometryElement == null)
                return;

            // export parts or not
            bool exportParts = PartExporter.CanExportParts(floorElement);
            if (exportParts && !PartExporter.CanExportElementInPartExport(floorElement, floorElement.LevelId, false))
                return;

            string ifcEnumType;
            IFCExportType exportType = ExporterUtil.GetExportType(exporterIFC, floorElement, out ifcEnumType);

            IFCFile file = exporterIFC.GetFile();
            IList<IFCAnyHandle> slabHnds = new List<IFCAnyHandle>();
            IList<IFCAnyHandle> brepSlabHnds = new List<IFCAnyHandle>();
            IList<IFCAnyHandle> nonBrepSlabHnds = new List<IFCAnyHandle>();
                        
            using (IFCTransaction tr = new IFCTransaction(file))
            {
                using (IFCTransformSetter transformSetter = IFCTransformSetter.Create())
                {
                    using (PlacementSetter placementSetter = PlacementSetter.Create(exporterIFC, floorElement))
                    {
                        IFCAnyHandle localPlacement = placementSetter.LocalPlacement;
                        IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle();
                        bool exportedAsInternalExtrusion = false;

                        ElementId catId = CategoryUtil.GetSafeCategoryId(floorElement);

                        IList<IFCAnyHandle> prodReps = new List<IFCAnyHandle>();
                        IList<ShapeRepresentationType> repTypes = new List<ShapeRepresentationType>();
                        IList<IList<CurveLoop>> extrusionLoops = new List<IList<CurveLoop>>();
                        IList<IFCExtrusionCreationData> loopExtraParams = new List<IFCExtrusionCreationData>();
                        Plane floorPlane = GeometryUtil.CreateDefaultPlane();

                        IList<IFCAnyHandle> localPlacements = new List<IFCAnyHandle>();

                        if (!exportParts && (floorElement is Floor))
                        {
                            Floor floor = floorElement as Floor;

                            // Try to use the ExtrusionAnalyzer for the limited cases it handles - 1 solid, no openings, end clippings only.
                            // Also limited to cases with line and arc boundaries.
                            //
                            SolidMeshGeometryInfo solidMeshInfo = GeometryUtil.GetSplitSolidMeshGeometry(geometryElement);
                            IList<Solid> solids = solidMeshInfo.GetSolids();
                            IList<Mesh> meshes = solidMeshInfo.GetMeshes();

                            if (solids.Count == 1 && meshes.Count == 0)
                            {
                                bool completelyClipped;
                                XYZ floorExtrusionDirection = new XYZ(0, 0, -1);
                                XYZ modelOrigin = XYZ.Zero;

                                XYZ floorOrigin = floor.GetVerticalProjectionPoint(modelOrigin, FloorFace.Top);
                                if (floorOrigin == null)
                                {
                                    // GetVerticalProjectionPoint may return null if FloorFace.Top is an edited face that doesn't 
                                    // go thruough te Revit model orgigin.  We'll try the midpoint of the bounding box instead.
                                    BoundingBoxXYZ boundingBox = floorElement.get_BoundingBox(null);
                                    modelOrigin = (boundingBox.Min + boundingBox.Max) / 2.0;
                                    floorOrigin = floor.GetVerticalProjectionPoint(modelOrigin, FloorFace.Top);
                                }

                                if (floorOrigin != null)
                                {
                                    XYZ floorDir = floor.GetNormalAtVerticalProjectionPoint(floorOrigin, FloorFace.Top);
                                    Plane extrusionAnalyzerFloorPlane = new Plane(floorDir, floorOrigin);

                                    HandleAndData floorAndProperties =
                                        ExtrusionExporter.CreateExtrusionWithClippingAndProperties(exporterIFC, floorElement,
                                        catId, solids[0], extrusionAnalyzerFloorPlane, floorExtrusionDirection, null, out completelyClipped);
                                    if (completelyClipped)
                                        return;
                                    if (floorAndProperties.Handle != null)
                                    {
                                        IList<IFCAnyHandle> representations = new List<IFCAnyHandle>();
                                        representations.Add(floorAndProperties.Handle);
                                        IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, representations);
                                        prodReps.Add(prodRep);
                                        repTypes.Add(ShapeRepresentationType.SweptSolid);

                                        if (floorAndProperties.Data != null)
                                            loopExtraParams.Add(floorAndProperties.Data);
                                    }
                                }
                            }
                        }
                     
                        // Use internal routine as backup that handles openings.
                        if (prodReps.Count == 0)
                        {
                            exportedAsInternalExtrusion = ExporterIFCUtils.ExportSlabAsExtrusion(exporterIFC, floorElement,
                                geometryElement, transformSetter, localPlacement, out localPlacements, out prodReps,
                                out extrusionLoops, out loopExtraParams, floorPlane);
                            for (int ii = 0; ii < prodReps.Count; ii++)
                            {
                                // all are extrusions
                                repTypes.Add(ShapeRepresentationType.SweptSolid);
                            }
                        }

                        if (prodReps.Count == 0)
                        {
                            using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                            {
                                BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true);
                                bodyExporterOptions.TessellationLevel = BodyExporter.GetTessellationLevel();
                                BodyData bodyData;
                                IFCAnyHandle prodDefHnd = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC,
                                    floorElement, catId, geometryElement, bodyExporterOptions, null, ecData, out bodyData);
                                if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodDefHnd))
                                {
                                    ecData.ClearOpenings();
                                    return;
                                }

                                prodReps.Add(prodDefHnd);
                                repTypes.Add(bodyData.ShapeRepresentationType);
                            }
                        }
                    
                        // Create the slab from either the extrusion or the BRep information.
                        string ifcGUID = GUIDUtil.CreateGUID(floorElement);

                        int numReps = exportParts ? 1 : prodReps.Count;

                        string entityType = null;

                        switch (exportType)
                        {
                            case IFCExportType.IfcFooting:
                                if (ExporterCacheManager.ExportOptionsCache.ExportAs4)
                                    entityType = IFCValidateEntry.GetValidIFCType<Revit.IFC.Export.Toolkit.IFC4.IFCFootingType>(floorElement, ifcEnumType, null);
                                else
                                    entityType = IFCValidateEntry.GetValidIFCType<IFCFootingType>(floorElement, ifcEnumType, null);
                                break;
                            case IFCExportType.IfcCovering:
                                entityType = IFCValidateEntry.GetValidIFCType<IFCCoveringType>(floorElement, ifcEnumType, "FLOORING");
                                break;
                            case IFCExportType.IfcRamp:
                                if (ExporterCacheManager.ExportOptionsCache.ExportAs4)
                                    entityType = IFCValidateEntry.GetValidIFCType<Revit.IFC.Export.Toolkit.IFC4.IFCRampType>(floorElement, ifcEnumType, null);
                                else
                                    entityType = IFCValidateEntry.GetValidIFCType<IFCRampType>(floorElement, ifcEnumType, null);
                                break;
                            default:
                                bool isBaseSlab = false;
                                AnalyticalModel analyticalModel = floorElement.GetAnalyticalModel();
                                if (analyticalModel != null)
                                {
                                    AnalyzeAs slabFoundationType = analyticalModel.GetAnalyzeAs();
                                    isBaseSlab = (slabFoundationType == AnalyzeAs.SlabOnGrade) || (slabFoundationType == AnalyzeAs.Mat);
                                }
                                entityType = IFCValidateEntry.GetValidIFCType<IFCSlabType>(floorElement, ifcEnumType, isBaseSlab ? "BASESLAB" : "FLOOR");
                                break;
                        }
                        
                        for (int ii = 0; ii < numReps; ii++)
                        {
                            string ifcName = NamingUtil.GetNameOverride(floorElement, NamingUtil.GetIFCNamePlusIndex(floorElement, ii == 0 ? -1 : ii + 1));
                            string ifcDescription = NamingUtil.GetDescriptionOverride(floorElement, null);
                            string ifcObjectType = NamingUtil.GetObjectTypeOverride(floorElement, exporterIFC.GetFamilyName());
                            string ifcTag = NamingUtil.GetTagOverride(floorElement, NamingUtil.CreateIFCElementId(floorElement));

                            string currentGUID = (ii == 0) ? ifcGUID : GUIDUtil.CreateGUID();
                            IFCAnyHandle localPlacementHnd = exportedAsInternalExtrusion ? localPlacements[ii] : localPlacement;

                            IFCAnyHandle slabHnd = null;

                            // TODO: replace with CreateGenericBuildingElement.
                            switch (exportType)
                            {
                                case IFCExportType.IfcFooting:
                                    slabHnd = IFCInstanceExporter.CreateFooting(file, currentGUID, ownerHistory, ifcName,
                                        ifcDescription, ifcObjectType, localPlacementHnd, exportParts ? null : prodReps[ii],
                                        ifcTag, entityType);
                                    break;
                                case IFCExportType.IfcCovering:
                                    slabHnd = IFCInstanceExporter.CreateCovering(file, currentGUID, ownerHistory, ifcName,
                                        ifcDescription, ifcObjectType, localPlacementHnd, exportParts ? null : prodReps[ii],
                                        ifcTag, entityType); 
                                    break;
                                case IFCExportType.IfcRamp:
                                    slabHnd = IFCInstanceExporter.CreateRamp(file, currentGUID, ownerHistory, ifcName,
                                        ifcDescription, ifcObjectType, localPlacementHnd, exportParts ? null : prodReps[ii],
                                        ifcTag, entityType);
                                    break;
                                default:
                                    slabHnd = IFCInstanceExporter.CreateSlab(file, currentGUID, ownerHistory, ifcName,
                                        ifcDescription, ifcObjectType, localPlacementHnd, exportParts ? null : prodReps[ii],
                                        ifcTag, entityType);
                                    break;
                            }

                            if (IFCAnyHandleUtil.IsNullOrHasNoValue(slabHnd))
                                return;

                            if (exportParts)
                                PartExporter.ExportHostPart(exporterIFC, floorElement, slabHnd, productWrapper, placementSetter, localPlacementHnd, null);

                            slabHnds.Add(slabHnd);

                            if (!exportParts)
                            {
                                if (repTypes[ii] == ShapeRepresentationType.Brep)
                                    brepSlabHnds.Add(slabHnd);
                                else
                                    nonBrepSlabHnds.Add(slabHnd);
                            }
                        }

                        for (int ii = 0; ii < numReps; ii++)
                        {
                            IFCExtrusionCreationData loopExtraParam = ii < loopExtraParams.Count ? loopExtraParams[ii] : null;
                            productWrapper.AddElement(floorElement, slabHnds[ii], placementSetter, loopExtraParam, true);
                        }

                        // This call to the native function appears to create Brep opening also when appropriate. But the creation of the IFC instances is not
                        //   controllable from the managed code. Therefore in some cases BRep geometry for Opening will still be exported even in the Reference View
                        if (exportedAsInternalExtrusion)
                            ExporterIFCUtils.ExportExtrudedSlabOpenings(exporterIFC, floorElement, placementSetter.LevelInfo,
                               localPlacements[0], slabHnds, extrusionLoops, floorPlane, productWrapper.ToNative());
                    }

                    if (!exportParts)
                    {
                        if (nonBrepSlabHnds.Count > 0)
                        {
                            HostObjectExporter.ExportHostObjectMaterials(exporterIFC, floorElement, nonBrepSlabHnds,
                                geometryElement, productWrapper, ElementId.InvalidElementId, Toolkit.IFCLayerSetDirection.Axis3, false);
                        }
                        if (brepSlabHnds.Count > 0)
                        {
                            HostObjectExporter.ExportHostObjectMaterials(exporterIFC, floorElement, brepSlabHnds,
                                geometryElement, productWrapper, ElementId.InvalidElementId, Toolkit.IFCLayerSetDirection.Axis3, true);
                        }
                    }
                }
                tr.Commit();

                return;
            }
    }
        /// <summary>
        /// Exports a generic element as an IfcSlab.</summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="floor">The floor element.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="ifcEnumType">The string value represents the IFC type.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        /// <returns>True if the floor is exported successfully, false otherwise.</returns>
        public static void ExportGenericSlab(ExporterIFC exporterIFC, Element slabElement, GeometryElement geometryElement, string ifcEnumType,
            ProductWrapper productWrapper)
        {
            if (geometryElement == null)
                return;

            IFCFile file = exporterIFC.GetFile();

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                using (IFCTransformSetter transformSetter = IFCTransformSetter.Create())
                {
                    using (PlacementSetter placementSetter = PlacementSetter.Create(exporterIFC, slabElement))
                    {
                        using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                        {
                            bool exportParts = PartExporter.CanExportParts(slabElement);
                            
                            IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle();
                            IFCAnyHandle localPlacement = placementSetter.LocalPlacement;
                            
                            IFCAnyHandle prodDefHnd = null;
                            bool isBRepSlabHnd = false;
                            
                            if (!exportParts)
                            {
                                ecData.SetLocalPlacement(localPlacement);

                                ElementId catId = CategoryUtil.GetSafeCategoryId(slabElement);

                                BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true);
                                bodyExporterOptions.TessellationLevel = BodyExporter.GetTessellationLevel();
                                BodyData bodyData;
                                prodDefHnd = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC,
                                    slabElement, catId, geometryElement, bodyExporterOptions, null, ecData, out bodyData);
                                if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodDefHnd))
                                {
                                    ecData.ClearOpenings();
                                    return;
                                }
                                isBRepSlabHnd = (bodyData.ShapeRepresentationType == ShapeRepresentationType.Brep);
                            }

                            // Create the slab from either the extrusion or the BRep information.
                            string ifcGUID = GUIDUtil.CreateGUID(slabElement);

                            string entityType = IFCValidateEntry.GetValidIFCType<IFCSlabType>(slabElement, ifcEnumType, "FLOOR");

                            string ifcName = NamingUtil.GetNameOverride(slabElement, NamingUtil.GetIFCName(slabElement));
                            string ifcDescription = NamingUtil.GetDescriptionOverride(slabElement, null);
                            string ifcObjectType = NamingUtil.GetObjectTypeOverride(slabElement, exporterIFC.GetFamilyName());
                            string ifcTag = NamingUtil.GetTagOverride(slabElement, NamingUtil.CreateIFCElementId(slabElement));

                            IFCAnyHandle slabHnd = IFCInstanceExporter.CreateSlab(file, ifcGUID, ownerHistory, ifcName,
                                    ifcDescription, ifcObjectType, localPlacement, exportParts ? null : prodDefHnd,
                                    ifcTag, entityType);

                            if (IFCAnyHandleUtil.IsNullOrHasNoValue(slabHnd))
                                return;

                            if (exportParts)
                                PartExporter.ExportHostPart(exporterIFC, slabElement, slabHnd, productWrapper, placementSetter, localPlacement, null);

                            productWrapper.AddElement(slabElement, slabHnd, placementSetter, ecData, true);

                            if (!exportParts)
                            {
                                if (slabElement is HostObject)
                                {
                                    HostObject hostObject = slabElement as HostObject;

                                    HostObjectExporter.ExportHostObjectMaterials(exporterIFC, hostObject, slabHnd,
                                        geometryElement, productWrapper, ElementId.InvalidElementId, Toolkit.IFCLayerSetDirection.Axis3, isBRepSlabHnd);
                                }
                                else if (slabElement is FamilyInstance)
                                {
                                    ElementId matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geometryElement, exporterIFC, slabElement);
                                    Document doc = slabElement.Document;
                                    CategoryUtil.CreateMaterialAssociation(exporterIFC, slabHnd, matId);
                                }

                                OpeningUtil.CreateOpeningsIfNecessary(slabHnd, slabElement, ecData, null, 
                                    exporterIFC, ecData.GetLocalPlacement(), placementSetter, productWrapper);
                            }
                        }
                    }
                    tr.Commit();

                    return;
                }
            }
        }
Пример #14
0
        /// <summary>
        /// Creates a SweptSolidExporter.
        /// </summary>
        /// <param name="exporterIFC">The exporter.</param>
        /// <param name="element">The element.</param>
        /// <param name="solid">The solid.</param>
        /// <param name="normal">The normal of the plane that the path lies on.</param>
        /// <returns>The SweptSolidExporter.</returns>
        public static SweptSolidExporter Create(ExporterIFC exporterIFC, Element element, SimpleSweptSolidAnalyzer sweptAnalyzer, GeometryObject geomObject)
        {
            try
            {
                if (sweptAnalyzer == null)
                {
                    return(null);
                }

                SweptSolidExporter sweptSolidExporter = null;

                IList <Revit.IFC.Export.Utility.GeometryUtil.FaceBoundaryType> faceBoundaryTypes;
                IList <CurveLoop> faceBoundaries = GeometryUtil.GetFaceBoundaries(sweptAnalyzer.ProfileFace, null, out faceBoundaryTypes);

                string profileName = null;
                if (element != null)
                {
                    ElementType type = element.Document.GetElement(element.GetTypeId()) as ElementType;
                    if (type != null)
                    {
                        profileName = type.Name;
                    }
                }

                // Is it really an extrusion?
                if (sweptAnalyzer.PathCurve is Line)
                {
                    Line line = sweptAnalyzer.PathCurve as Line;

                    // invalid case
                    if (MathUtil.VectorsAreOrthogonal(line.Direction, sweptAnalyzer.ProfileFace.Normal))
                    {
                        return(null);
                    }

                    sweptSolidExporter = new SweptSolidExporter();
                    sweptSolidExporter.RepresentationType = ShapeRepresentationType.SweptSolid;
                    Plane plane = new Plane(sweptAnalyzer.ProfileFace.Normal, sweptAnalyzer.ProfileFace.Origin);
                    sweptSolidExporter.RepresentationItem = ExtrusionExporter.CreateExtrudedSolidFromCurveLoop(exporterIFC, profileName, faceBoundaries, plane,
                                                                                                               line.Direction, UnitUtil.ScaleLength(line.Length));
                }
                else
                {
                    sweptSolidExporter = new SweptSolidExporter();
                    if (ExporterCacheManager.ExportOptionsCache.ExportAs4)
                    {
                        // Use tessellated geometry in IFC Reference View
                        if (ExporterUtil.IsReferenceView())
                        {
                            // TODO: Create CreateSimpleSweptSolidAsTessellation routine that takes advantage of the superior tessellation of this class.
                            BodyExporterOptions options = new BodyExporterOptions(false);
                            sweptSolidExporter.RepresentationItem = BodyExporter.ExportBodyAsTriangulatedFaceSet(exporterIFC, element, options, geomObject);
                            sweptSolidExporter.RepresentationType = ShapeRepresentationType.Tessellation;
                        }
                        else
                        {
                            sweptSolidExporter.RepresentationItem = CreateSimpleSweptSolid(exporterIFC, profileName, faceBoundaries, sweptAnalyzer.ReferencePlaneNormal, sweptAnalyzer.PathCurve);
                            sweptSolidExporter.RepresentationType = ShapeRepresentationType.AdvancedSweptSolid;
                        }
                    }
                    else
                    {
                        sweptSolidExporter.Facets             = CreateSimpleSweptSolidAsBRep(exporterIFC, profileName, faceBoundaries, sweptAnalyzer.ReferencePlaneNormal, sweptAnalyzer.PathCurve);
                        sweptSolidExporter.RepresentationType = ShapeRepresentationType.Brep;
                    }
                }
                return(sweptSolidExporter);
            }
            catch (Exception)
            {
                return(null);
            }
        }
Пример #15
0
        /// <summary>
        /// Exports a generic element as an IfcSlab.</summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="floor">The floor element.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="ifcEnumType">The string value represents the IFC type.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        /// <returns>True if the floor is exported successfully, false otherwise.</returns>
        public static void ExportGenericSlab(ExporterIFC exporterIFC, Element slabElement, GeometryElement geometryElement, string ifcEnumType,
            ProductWrapper productWrapper)
        {
            if (geometryElement == null)
                return;

            bool exportParts = PartExporter.CanExportParts(slabElement);
                    
            IFCFile file = exporterIFC.GetFile();
            IList<IFCAnyHandle> slabHnds = new List<IFCAnyHandle>();
            IList<IFCAnyHandle> brepSlabHnds = new List<IFCAnyHandle>();
            IList<IFCAnyHandle> nonBrepSlabHnds = new List<IFCAnyHandle>();

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                using (IFCTransformSetter transformSetter = IFCTransformSetter.Create())
                {
                    using (PlacementSetter placementSetter = PlacementSetter.Create(exporterIFC, slabElement))
                    {
                        IFCAnyHandle localPlacement = placementSetter.LocalPlacement;
                        IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle();
                        bool exportedAsInternalExtrusion = false;

                        ElementId catId = CategoryUtil.GetSafeCategoryId(slabElement);

                        IList<IFCAnyHandle> prodReps = new List<IFCAnyHandle>();
                        IList<ShapeRepresentationType> repTypes = new List<ShapeRepresentationType>();
                        IList<IList<CurveLoop>> extrusionLoops = new List<IList<CurveLoop>>();
                        IList<IFCExtrusionCreationData> loopExtraParams = new List<IFCExtrusionCreationData>();
                        Plane floorPlane = GeometryUtil.CreateDefaultPlane();

                        IList<IFCAnyHandle> localPlacements = new List<IFCAnyHandle>();

                        using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                        {
                            BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true);
                            bodyExporterOptions.TessellationLevel = BodyExporter.GetTessellationLevel();
                            BodyData bodyData;
                            IFCAnyHandle prodDefHnd = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC,
                                slabElement, catId, geometryElement, bodyExporterOptions, null, ecData, out bodyData);
                            if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodDefHnd))
                            {
                                ecData.ClearOpenings();
                                return;
                            }

                            prodReps.Add(prodDefHnd);
                            repTypes.Add(bodyData.ShapeRepresentationType);
                        }

                        // Create the slab from either the extrusion or the BRep information.
                        string ifcGUID = GUIDUtil.CreateGUID(slabElement);

                        int numReps = exportParts ? 1 : prodReps.Count;

                        string entityType = IFCValidateEntry.GetValidIFCType<IFCSlabType>(slabElement, ifcEnumType, "FLOOR");

                        for (int ii = 0; ii < numReps; ii++)
                        {
                            string ifcName = NamingUtil.GetNameOverride(slabElement, NamingUtil.GetIFCNamePlusIndex(slabElement, ii == 0 ? -1 : ii + 1));
                            string ifcDescription = NamingUtil.GetDescriptionOverride(slabElement, null);
                            string ifcObjectType = NamingUtil.GetObjectTypeOverride(slabElement, exporterIFC.GetFamilyName());
                            string ifcTag = NamingUtil.GetTagOverride(slabElement, NamingUtil.CreateIFCElementId(slabElement));

                            string currentGUID = (ii == 0) ? ifcGUID : GUIDUtil.CreateGUID();
                            IFCAnyHandle localPlacementHnd = exportedAsInternalExtrusion ? localPlacements[ii] : localPlacement;

                            IFCAnyHandle slabHnd = IFCInstanceExporter.CreateSlab(file, currentGUID, ownerHistory, ifcName,
                                    ifcDescription, ifcObjectType, localPlacementHnd, exportParts ? null : prodReps[ii],
                                    ifcTag, entityType);

                            if (IFCAnyHandleUtil.IsNullOrHasNoValue(slabHnd))
                                return;

                            if (exportParts)
                            {
                                PartExporter.ExportHostPart(exporterIFC, slabElement, slabHnd, productWrapper, placementSetter, localPlacementHnd, null);
                            }

                            slabHnds.Add(slabHnd);

                            if (!exportParts)
                            {
                                if (repTypes[ii] == ShapeRepresentationType.Brep)
                                    brepSlabHnds.Add(slabHnd);
                                else
                                    nonBrepSlabHnds.Add(slabHnd);
                            }
                        }

                        for (int ii = 0; ii < numReps; ii++)
                        {
                            IFCExtrusionCreationData loopExtraParam = ii < loopExtraParams.Count ? loopExtraParams[ii] : null;
                            productWrapper.AddElement(slabElement, slabHnds[ii], placementSetter, loopExtraParam, true);
                        }

                        if (exportedAsInternalExtrusion)
                            ExporterIFCUtils.ExportExtrudedSlabOpenings(exporterIFC, slabElement, placementSetter.LevelInfo,
                               localPlacements[0], slabHnds, extrusionLoops, floorPlane, productWrapper.ToNative());
                    }

                    if (!exportParts)
                    {
                        if (slabElement is HostObject)
                        {
                            HostObject hostObject = slabElement as HostObject;
                            if (nonBrepSlabHnds.Count > 0)
                            {
                                HostObjectExporter.ExportHostObjectMaterials(exporterIFC, hostObject, nonBrepSlabHnds,
                                    geometryElement, productWrapper, ElementId.InvalidElementId, Toolkit.IFCLayerSetDirection.Axis3, false);
                            }
                            if (brepSlabHnds.Count > 0)
                            {
                                HostObjectExporter.ExportHostObjectMaterials(exporterIFC, hostObject, brepSlabHnds,
                                    geometryElement, productWrapper, ElementId.InvalidElementId, Toolkit.IFCLayerSetDirection.Axis3, true);
                            }
                        }
                        else if (slabElement is FamilyInstance && slabHnds.Count > 0)
                        {
                            ElementId matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geometryElement, exporterIFC, slabElement);
                            Document doc = slabElement.Document;
                            foreach (IFCAnyHandle slabHnd in slabHnds)
                            {
                                CategoryUtil.CreateMaterialAssociation(exporterIFC, slabHnd, matId);
                            }
                        }
                    }
                }
                tr.Commit();

                return;
            }
        }
Пример #16
0
        /// <summary>
        /// Exports a generic element as an IfcSlab.</summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="floor">The floor element.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="ifcEnumType">The string value represents the IFC type.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        /// <returns>True if the floor is exported successfully, false otherwise.</returns>
        public static void ExportGenericSlab(ExporterIFC exporterIFC, Element slabElement, GeometryElement geometryElement, string ifcEnumType,
                                             ProductWrapper productWrapper)
        {
            if (geometryElement == null)
            {
                return;
            }

            bool exportParts = PartExporter.CanExportParts(slabElement);

            IFCFile file = exporterIFC.GetFile();
            IList <IFCAnyHandle> slabHnds        = new List <IFCAnyHandle>();
            IList <IFCAnyHandle> brepSlabHnds    = new List <IFCAnyHandle>();
            IList <IFCAnyHandle> nonBrepSlabHnds = new List <IFCAnyHandle>();

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                using (IFCTransformSetter transformSetter = IFCTransformSetter.Create())
                {
                    using (PlacementSetter placementSetter = PlacementSetter.Create(exporterIFC, slabElement))
                    {
                        IFCAnyHandle localPlacement = placementSetter.LocalPlacement;
                        IFCAnyHandle ownerHistory   = exporterIFC.GetOwnerHistoryHandle();
                        bool         exportedAsInternalExtrusion = false;

                        ElementId catId = CategoryUtil.GetSafeCategoryId(slabElement);

                        IList <IFCAnyHandle>             prodReps        = new List <IFCAnyHandle>();
                        IList <ShapeRepresentationType>  repTypes        = new List <ShapeRepresentationType>();
                        IList <IList <CurveLoop> >       extrusionLoops  = new List <IList <CurveLoop> >();
                        IList <IFCExtrusionCreationData> loopExtraParams = new List <IFCExtrusionCreationData>();
                        Plane floorPlane = GeometryUtil.CreateDefaultPlane();

                        IList <IFCAnyHandle> localPlacements = new List <IFCAnyHandle>();

                        using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                        {
                            BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true);
                            bodyExporterOptions.TessellationLevel = BodyExporter.GetTessellationLevel();
                            BodyData     bodyData;
                            IFCAnyHandle prodDefHnd = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC,
                                                                                                                 slabElement, catId, geometryElement, bodyExporterOptions, null, ecData, out bodyData);
                            if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodDefHnd))
                            {
                                ecData.ClearOpenings();
                                return;
                            }

                            prodReps.Add(prodDefHnd);
                            repTypes.Add(bodyData.ShapeRepresentationType);
                        }

                        // Create the slab from either the extrusion or the BRep information.
                        string ifcGUID = GUIDUtil.CreateGUID(slabElement);

                        int numReps = exportParts ? 1 : prodReps.Count;

                        string entityType = IFCValidateEntry.GetValidIFCType <IFCSlabType>(slabElement, ifcEnumType, "FLOOR");

                        for (int ii = 0; ii < numReps; ii++)
                        {
                            string ifcName        = NamingUtil.GetNameOverride(slabElement, NamingUtil.GetIFCNamePlusIndex(slabElement, ii == 0 ? -1 : ii + 1));
                            string ifcDescription = NamingUtil.GetDescriptionOverride(slabElement, null);
                            string ifcObjectType  = NamingUtil.GetObjectTypeOverride(slabElement, exporterIFC.GetFamilyName());
                            string ifcTag         = NamingUtil.GetTagOverride(slabElement, NamingUtil.CreateIFCElementId(slabElement));

                            string       currentGUID       = (ii == 0) ? ifcGUID : GUIDUtil.CreateGUID();
                            IFCAnyHandle localPlacementHnd = exportedAsInternalExtrusion ? localPlacements[ii] : localPlacement;

                            IFCAnyHandle slabHnd = IFCInstanceExporter.CreateSlab(file, currentGUID, ownerHistory, ifcName,
                                                                                  ifcDescription, ifcObjectType, localPlacementHnd, exportParts ? null : prodReps[ii],
                                                                                  ifcTag, entityType);

                            if (IFCAnyHandleUtil.IsNullOrHasNoValue(slabHnd))
                            {
                                return;
                            }

                            if (exportParts)
                            {
                                PartExporter.ExportHostPart(exporterIFC, slabElement, slabHnd, productWrapper, placementSetter, localPlacementHnd, null);
                            }

                            slabHnds.Add(slabHnd);

                            if (!exportParts)
                            {
                                if (repTypes[ii] == ShapeRepresentationType.Brep)
                                {
                                    brepSlabHnds.Add(slabHnd);
                                }
                                else
                                {
                                    nonBrepSlabHnds.Add(slabHnd);
                                }
                            }
                        }

                        for (int ii = 0; ii < numReps; ii++)
                        {
                            IFCExtrusionCreationData loopExtraParam = ii < loopExtraParams.Count ? loopExtraParams[ii] : null;
                            productWrapper.AddElement(slabElement, slabHnds[ii], placementSetter, loopExtraParam, true);
                        }

                        if (exportedAsInternalExtrusion)
                        {
                            ExporterIFCUtils.ExportExtrudedSlabOpenings(exporterIFC, slabElement, placementSetter.LevelInfo,
                                                                        localPlacements[0], slabHnds, extrusionLoops, floorPlane, productWrapper.ToNative());
                        }
                    }

                    if (!exportParts)
                    {
                        if (slabElement is HostObject)
                        {
                            HostObject hostObject = slabElement as HostObject;
                            if (nonBrepSlabHnds.Count > 0)
                            {
                                HostObjectExporter.ExportHostObjectMaterials(exporterIFC, hostObject, nonBrepSlabHnds,
                                                                             geometryElement, productWrapper, ElementId.InvalidElementId, Toolkit.IFCLayerSetDirection.Axis3, false);
                            }
                            if (brepSlabHnds.Count > 0)
                            {
                                HostObjectExporter.ExportHostObjectMaterials(exporterIFC, hostObject, brepSlabHnds,
                                                                             geometryElement, productWrapper, ElementId.InvalidElementId, Toolkit.IFCLayerSetDirection.Axis3, true);
                            }
                        }
                        else if (slabElement is FamilyInstance && slabHnds.Count > 0)
                        {
                            ElementId matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geometryElement, exporterIFC, slabElement);
                            Document  doc   = slabElement.Document;
                            foreach (IFCAnyHandle slabHnd in slabHnds)
                            {
                                CategoryUtil.CreateMaterialAssociation(exporterIFC, slabHnd, matId);
                            }
                        }
                    }
                }
                tr.Commit();

                return;
            }
        }
Пример #17
0
        /// <summary>
        /// Exports an element to IfcPile.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="element">The element.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="ifcEnumType">The string value represents the IFC type.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        public static void ExportPile(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement,
           string ifcEnumType, ProductWrapper productWrapper)
        {
            // export parts or not
            bool exportParts = PartExporter.CanExportParts(element);
            if (exportParts && !PartExporter.CanExportElementInPartExport(element, element.LevelId, false))
                return;

            IFCFile file = exporterIFC.GetFile();

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element))
                {
                    using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                    {                      
                        ecData.SetLocalPlacement(setter.LocalPlacement);
                      
                        IFCAnyHandle prodRep = null;
                        ElementId matId = ElementId.InvalidElementId;
                        if (!exportParts)
                        {
                            ElementId catId = CategoryUtil.GetSafeCategoryId(element);


                            matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geometryElement, exporterIFC, element);
                            BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true);
                            prodRep = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC,
                               element, catId, geometryElement, bodyExporterOptions, null, ecData, true);
                            if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodRep))
                            {
                                ecData.ClearOpenings();
                                return;
                            }
                        }

                        string instanceGUID = GUIDUtil.CreateGUID(element);
                        string instanceName = NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element));
                        string instanceDescription = NamingUtil.GetDescriptionOverride(element, null);
                        string instanceObjectType = NamingUtil.GetObjectTypeOverride(element, exporterIFC.GetFamilyName());
                        string instanceTag = NamingUtil.GetTagOverride(element, NamingUtil.CreateIFCElementId(element));
                        string pileType = IFCValidateEntry.GetValidIFCType(element, ifcEnumType);

                        IFCAnyHandle pile = IFCInstanceExporter.CreatePile(file, instanceGUID, ExporterCacheManager.OwnerHistoryHandle,
                            instanceName, instanceDescription, instanceObjectType, ecData.GetLocalPlacement(), prodRep, instanceTag, pileType, null);

                        if (exportParts)
                        {
                            PartExporter.ExportHostPart(exporterIFC, element, pile, productWrapper, setter, setter.LocalPlacement, null);
                        }
                        else
                        {
                            if (matId != ElementId.InvalidElementId)
                            {
                                CategoryUtil.CreateMaterialAssociation(exporterIFC, pile, matId);
                            }
                        }

                        productWrapper.AddElement(element, pile, setter, ecData, true);

                        OpeningUtil.CreateOpeningsIfNecessary(pile, element, ecData, null,
                            exporterIFC, ecData.GetLocalPlacement(), setter, productWrapper);
                    }
                }

                tr.Commit();
            }
        }
Пример #18
0
        /// <summary>
        /// Export Geometry in IFC4 Triangulated tessellation
        /// </summary>
        /// <param name="exporterIFC">the exporter</param>
        /// <param name="element">the element</param>
        /// <param name="options">the options</param>
        /// <param name="geomObject">geometry objects</param>
        /// <returns>returns a handle</returns>
        public static IFCAnyHandle ExportBodyAsTriangulatedFaceSet(ExporterIFC exporterIFC, Element element, BodyExporterOptions options,
                    GeometryObject geomObject)
        {
            IFCFile file = exporterIFC.GetFile();
            Document document = element.Document;

            IFCAnyHandle triangulatedBody = null;

            if (geomObject is Solid)
            {
                try
                {
                    Solid solid = geomObject as Solid;

                    SolidOrShellTessellationControls tessellationControls = options.TessellationControls;
                    // Convert integer level of detail into a 0 to 1 scale.
                    tessellationControls.LevelOfDetail = ((double)ExporterCacheManager.ExportOptionsCache.LevelOfDetail) / 4.0;

                    TriangulatedSolidOrShell solidFacetation =
                        SolidUtils.TessellateSolidOrShell(solid, tessellationControls);

                    // Only handle one solid or shell.
                    if (solidFacetation.ShellComponentCount == 1)
                    {
                        TriangulatedShellComponent component = solidFacetation.GetShellComponent(0);
                        int numberOfTriangles = component.TriangleCount;
                        int numberOfVertices = component.VertexCount;

                        // We are going to limit the number of triangles to 50,000.  This is a arbitrary number
                        // that should prevent the solid faceter from creating too many extra triangles to sew the surfaces.
                        // We may evaluate this number over time.
                        if ((numberOfTriangles > 0 && numberOfVertices > 0) && (numberOfTriangles < 50000))
                        {
                            IList<IList<double>> coordList = new List<IList<double>>();
                            IList<IList<int>> coordIdx = new List<IList<int>>();

                            // create list of vertices first.
                            for (int i = 0; i < numberOfVertices; i++)
                            {
                                List<double> vertCoord = new List<double>();

                                XYZ vertex = component.GetVertex(i);
                                XYZ vertexScaled = ExporterIFCUtils.TransformAndScalePoint(exporterIFC, vertex);
                                vertCoord.Add(vertexScaled.X);
                                vertCoord.Add(vertexScaled.Y);
                                vertCoord.Add(vertexScaled.Z);
                                coordList.Add(vertCoord);
                            }
                            // Create the entity IfcCartesianPointList3D from the List of List<double> and assign it to attribute Coordinates of IfcTriangulatedFaceSet

                            // Export all of the triangles
                            for (int i = 0; i < numberOfTriangles; i++)
                            {
                                List<int> vertIdx = new List<int>();

                                TriangleInShellComponent triangle = component.GetTriangle(i);
                                vertIdx.Add(triangle.VertexIndex0 + 1);     // IFC uses index that starts with 1 instead of 0 (following similar standard in X3D)
                                vertIdx.Add(triangle.VertexIndex1 + 1);
                                vertIdx.Add(triangle.VertexIndex2 + 1);
                                coordIdx.Add(vertIdx);
                            }

                            // Create attribute CoordIndex from the List of List<int> of the IfcTriangulatedFaceSet

                            IFCAnyHandle coordPointLists = IFCAnyHandleUtil.CreateInstance(file, IFCEntityType.IfcCartesianPointList3D);
                            IFCAnyHandleUtil.SetAttribute(coordPointLists, "CoordList", coordList, 1, null, 3, 3);

                            triangulatedBody = IFCAnyHandleUtil.CreateInstance(file, IFCEntityType.IfcTriangulatedFaceSet);
                            IFCAnyHandleUtil.SetAttribute(triangulatedBody, "Coordinates", coordPointLists);
                            IFCAnyHandleUtil.SetAttribute(triangulatedBody, "CoordIndex", coordIdx, 1, null, 3, 3);
                        }
                    }
                }
                catch
                {
                    // Failed! Likely because of the tessellation failed. Try to create from the faceset instead
                    return ExportSurfaceAsTriangulatedFaceSet(exporterIFC, element, options, geomObject);
                }
            }
            else
            {
                // It is not from Solid, so we will use the faces to export. It works for Surface export too
                triangulatedBody = ExportSurfaceAsTriangulatedFaceSet(exporterIFC, element, options, geomObject);
            }
            return triangulatedBody;
        }
Пример #19
0
        /// <summary>
        /// Exports a generic element as an IfcSlab.</summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="floor">The floor element.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="ifcEnumType">The string value represents the IFC type.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        /// <returns>True if the floor is exported successfully, false otherwise.</returns>
        public static void ExportGenericSlab(ExporterIFC exporterIFC, Element slabElement, GeometryElement geometryElement, string ifcEnumType,
                                             ProductWrapper productWrapper)
        {
            if (geometryElement == null)
            {
                return;
            }

            IFCFile file = exporterIFC.GetFile();

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                using (IFCTransformSetter transformSetter = IFCTransformSetter.Create())
                {
                    using (PlacementSetter placementSetter = PlacementSetter.Create(exporterIFC, slabElement))
                    {
                        using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                        {
                            bool exportParts = PartExporter.CanExportParts(slabElement);

                            IFCAnyHandle ownerHistory   = ExporterCacheManager.OwnerHistoryHandle;
                            IFCAnyHandle localPlacement = placementSetter.LocalPlacement;

                            IFCAnyHandle prodDefHnd    = null;
                            bool         isBRepSlabHnd = false;

                            if (!exportParts)
                            {
                                ecData.SetLocalPlacement(localPlacement);

                                ElementId catId = CategoryUtil.GetSafeCategoryId(slabElement);

                                BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.Medium);
                                BodyData            bodyData;
                                prodDefHnd = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC,
                                                                                                        slabElement, catId, geometryElement, bodyExporterOptions, null, ecData, out bodyData);
                                if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodDefHnd))
                                {
                                    ecData.ClearOpenings();
                                    return;
                                }
                                isBRepSlabHnd = (bodyData.ShapeRepresentationType == ShapeRepresentationType.Brep || bodyData.ShapeRepresentationType == ShapeRepresentationType.Tessellation);
                            }

                            // Create the slab from either the extrusion or the BRep information.
                            string ifcGUID = GUIDUtil.CreateGUID(slabElement);

                            string entityType = IFCValidateEntry.GetValidIFCType <IFCSlabType>(slabElement, ifcEnumType, "FLOOR");

                            IFCAnyHandle slabHnd = IFCInstanceExporter.CreateSlab(exporterIFC, slabElement, ifcGUID, ownerHistory,
                                                                                  localPlacement, exportParts ? null : prodDefHnd, entityType);

                            if (IFCAnyHandleUtil.IsNullOrHasNoValue(slabHnd))
                            {
                                return;
                            }

                            if (exportParts)
                            {
                                PartExporter.ExportHostPart(exporterIFC, slabElement, slabHnd, productWrapper, placementSetter, localPlacement, null);
                            }

                            productWrapper.AddElement(slabElement, slabHnd, placementSetter, ecData, true);

                            if (!exportParts)
                            {
                                IFCExportInfoPair exportInfo = new IFCExportInfoPair(IFCEntityType.IfcSlab, IFCEntityType.IfcSlabType, entityType);
                                IFCAnyHandle      typeHnd    = ExporterUtil.CreateGenericTypeFromElement(slabElement, exportInfo, file, ownerHistory, entityType, productWrapper);
                                ExporterCacheManager.TypeRelationsCache.Add(typeHnd, slabHnd);

                                if (slabElement is HostObject)
                                {
                                    HostObject hostObject = slabElement as HostObject;

                                    HostObjectExporter.ExportHostObjectMaterials(exporterIFC, hostObject, slabHnd,
                                                                                 geometryElement, productWrapper, ElementId.InvalidElementId, Toolkit.IFCLayerSetDirection.Axis3, isBRepSlabHnd, typeHnd);
                                }
                                else if (slabElement is FamilyInstance)
                                {
                                    ElementId matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geometryElement, exporterIFC, slabElement);
                                    //Document doc = slabElement.Document;
                                    if (typeHnd != null)
                                    {
                                        CategoryUtil.CreateMaterialAssociation(exporterIFC, typeHnd, matId);
                                    }
                                    else
                                    {
                                        CategoryUtil.CreateMaterialAssociation(exporterIFC, slabHnd, matId);
                                    }
                                }

                                OpeningUtil.CreateOpeningsIfNecessary(slabHnd, slabElement, ecData, null,
                                                                      exporterIFC, ecData.GetLocalPlacement(), placementSetter, productWrapper);
                            }
                        }
                    }
                    tr.Commit();

                    return;
                }
            }
        }
Пример #20
0
        /// <summary>
        /// Return a triangulated face set from the list of faces
        /// </summary>
        /// <param name="exporterIFC">exporter IFC</param>
        /// <param name="element">the element</param>
        /// <param name="options">the body export options</param>
        /// <param name="geomObject">the geometry object</param>
        /// <returns>returns the handle</returns>
        private static IFCAnyHandle ExportSurfaceAsTriangulatedFaceSet(ExporterIFC exporterIFC, Element element, BodyExporterOptions options,
                    GeometryObject geomObject)
        {
            IFCFile file = exporterIFC.GetFile();

            List<List<XYZ>> triangleList = new List<List<XYZ>>();

            if (geomObject is Solid)
            {
                Solid geomSolid = geomObject as Solid;
                FaceArray faces = geomSolid.Faces;
                foreach (Face face in faces)
                {
                    double tessellationLevel = options.TessellationControls.LevelOfDetail;
                    Mesh faceTriangulation = face.Triangulate(tessellationLevel);
                    for (int i = 0; i < faceTriangulation.NumTriangles; ++i)
                    {
                        List<XYZ> triangleVertices = new List<XYZ>();
                        MeshTriangle triangle = faceTriangulation.get_Triangle(i);
                        for (int tri = 0; tri < 3; ++tri)
                        {
                            XYZ vert = triangle.get_Vertex(tri);
                            triangleVertices.Add(vert);
                        }
                        triangleList.Add(triangleVertices);
                    }
                }
            }
            else if (geomObject is Mesh)
            {
                Mesh geomMesh = geomObject as Mesh;
                for (int i = 0; i < geomMesh.NumTriangles; ++i)
                {
                    List<XYZ> triangleVertices = new List<XYZ>();
                    MeshTriangle triangle = geomMesh.get_Triangle(i);
                    for (int tri = 0; tri < 3; ++tri)
                    {
                        XYZ vert = triangle.get_Vertex(tri);
                        triangleVertices.Add(vert);
                    }
                    triangleList.Add(triangleVertices);
                }
            }
            return GeometryUtil.GetIndexedTriangles(file, triangleList);
        }
Пример #21
0
        /// <summary>
        /// Exports an element as IFC covering.
        /// </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 ExportCovering(ExporterIFC exporterIFC, Element element, GeometryElement geomElem, string ifcEnumType, ProductWrapper productWrapper)
        {
            bool exportParts = PartExporter.CanExportParts(element);

            if (exportParts && !PartExporter.CanExportElementInPartExport(element, element.LevelId, false))
            {
                return;
            }

            // Check the intended IFC entity or type name is in the exclude list specified in the UI
            Common.Enums.IFCEntityType elementClassTypeEnum = Common.Enums.IFCEntityType.IfcCovering;
            if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum))
            {
                return;
            }

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

            using (IFCTransaction transaction = new IFCTransaction(file))
            {
                using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element))
                {
                    using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                    {
                        ElementId categoryId = CategoryUtil.GetSafeCategoryId(element);

                        IFCAnyHandle prodRep = null;
                        if (!exportParts)
                        {
                            ecData.SetLocalPlacement(setter.LocalPlacement);
                            ecData.PossibleExtrusionAxes = IFCExtrusionAxes.TryZ;

                            BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow);
                            prodRep = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, element,
                                                                                                 categoryId, geomElem, bodyExporterOptions, null, ecData, true);
                            if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodRep))
                            {
                                ecData.ClearOpenings();
                                return;
                            }
                        }

                        // We will use the category of the element to set a default value for the covering.
                        string defaultCoveringEnumType = null;

                        if (categoryId == new ElementId(BuiltInCategory.OST_Ceilings))
                        {
                            defaultCoveringEnumType = "CEILING";
                        }
                        else if (categoryId == new ElementId(BuiltInCategory.OST_Floors))
                        {
                            defaultCoveringEnumType = "FLOORING";
                        }
                        else if (categoryId == new ElementId(BuiltInCategory.OST_Roofs))
                        {
                            defaultCoveringEnumType = "ROOFING";
                        }

                        string instanceGUID = GUIDUtil.CreateGUID(element);
                        string coveringType = IFCValidateEntry.GetValidIFCPredefinedTypeType(/*element,*/ ifcEnumType, defaultCoveringEnumType, "IfcCoveringType");

                        IFCAnyHandle covering = IFCInstanceExporter.CreateCovering(exporterIFC, element, instanceGUID, ExporterCacheManager.OwnerHistoryHandle,
                                                                                   setter.LocalPlacement, prodRep, coveringType);

                        if (exportParts)
                        {
                            PartExporter.ExportHostPart(exporterIFC, element, covering, productWrapper, setter, setter.LocalPlacement, null);
                        }

                        IFCExportInfoPair exportInfo = new IFCExportInfoPair(IFCEntityType.IfcCovering, IFCEntityType.IfcCoveringType, coveringType);
                        IFCAnyHandle      typeHnd    = ExporterUtil.CreateGenericTypeFromElement(element, exportInfo, file, ExporterCacheManager.OwnerHistoryHandle, coveringType, productWrapper);
                        ExporterCacheManager.TypeRelationsCache.Add(typeHnd, covering);

                        bool         containInSpace      = false;
                        IFCAnyHandle localPlacementToUse = setter.LocalPlacement;

                        // Ceiling containment in Space is generally required and not specific to any view
                        if (ExporterCacheManager.CeilingSpaceRelCache.ContainsKey(element.Id))
                        {
                            IList <ElementId> roomlist = ExporterCacheManager.CeilingSpaceRelCache[element.Id];

                            // Process Ceiling to be contained in a Space only when it is exactly bounding one Space
                            if (roomlist.Count == 1)
                            {
                                productWrapper.AddElement(element, covering, setter, null, false);

                                // Modify the Ceiling placement to be relative to the Space that it bounds
                                IFCAnyHandle roomPlacement     = IFCAnyHandleUtil.GetObjectPlacement(ExporterCacheManager.SpaceInfoCache.FindSpaceHandle(roomlist[0]));
                                Transform    relTrf            = ExporterIFCUtils.GetRelativeLocalPlacementOffsetTransform(roomPlacement, localPlacementToUse);
                                Transform    inverseTrf        = relTrf.Inverse;
                                IFCAnyHandle relLocalPlacement = ExporterUtil.CreateAxis2Placement3D(file, inverseTrf.Origin, inverseTrf.BasisZ, inverseTrf.BasisX);
                                IFCAnyHandleUtil.SetAttribute(localPlacementToUse, "PlacementRelTo", roomPlacement);
                                GeometryUtil.SetRelativePlacement(localPlacementToUse, relLocalPlacement);

                                ExporterCacheManager.SpaceInfoCache.RelateToSpace(roomlist[0], covering);
                                containInSpace = true;
                            }
                        }

                        // if not contained in Space, assign it to default containment in Level
                        if (!containInSpace)
                        {
                            productWrapper.AddElement(element, covering, setter, null, true);
                        }

                        if (!exportParts)
                        {
                            Ceiling ceiling = element as Ceiling;
                            if (ceiling != null)
                            {
                                HostObjectExporter.ExportHostObjectMaterials(exporterIFC, ceiling, covering,
                                                                             geomElem, productWrapper, ElementId.InvalidElementId, Toolkit.IFCLayerSetDirection.Axis3, null, null);
                            }
                            else
                            {
                                ElementId matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geomElem, exporterIFC, element);
                                CategoryUtil.CreateMaterialAssociation(exporterIFC, covering, matId);
                            }
                        }

                        OpeningUtil.CreateOpeningsIfNecessary(covering, element, ecData, null,
                                                              exporterIFC, ecData.GetLocalPlacement(), setter, productWrapper);
                    }
                }
                transaction.Commit();
            }
        }
Пример #22
0
        private static bool ExportBodyAsSolid(ExporterIFC exporterIFC, Element element, BodyExporterOptions options,
            IList<HashSet<IFCAnyHandle>> currentFaceHashSetList, GeometryObject geomObject)
        {
            IFCFile file = exporterIFC.GetFile();
            Document document = element.Document;
            bool exportedAsSolid = false;


            try
            {
                if (geomObject is Solid)
                {
                    Solid solid = geomObject as Solid;
                    exportedAsSolid = ExportPlanarBodyIfPossible(exporterIFC, solid, currentFaceHashSetList);
                    if (exportedAsSolid)
                        return exportedAsSolid;

                    SolidOrShellTessellationControls tessellationControlsOriginal = options.TessellationControls;
                    SolidOrShellTessellationControls tessellationControls = ExporterUtil.GetTessellationControl(element, tessellationControlsOriginal);

                    TriangulatedSolidOrShell solidFacetation = null;

                    // We will make (up to) 2 attempts.  First we will use tessellationControls, and then we will try tessellationControlsOriginal, but only
                    // if they are different.
                    for (int ii = 0; ii < 2; ii++)
                    {
                        if (ii == 1 && tessellationControls.Equals(tessellationControlsOriginal))
                            break;

                        try
                        {
                            SolidOrShellTessellationControls tessellationControlsToUse = (ii == 0) ? tessellationControls : tessellationControlsOriginal;
                            solidFacetation = SolidUtils.TessellateSolidOrShell(solid, tessellationControlsToUse);
                            break;
                        }
                        catch
                        {
                            solidFacetation = null;
                        }
                    }

                    // Only handle one solid or shell.
                    if (solidFacetation != null && solidFacetation.ShellComponentCount == 1)
                    {
                        TriangulatedShellComponent component = solidFacetation.GetShellComponent(0);
                        int numberOfTriangles = component.TriangleCount;
                        int numberOfVertices = component.VertexCount;

                        // We are going to limit the number of triangles to 50,000.  This is a arbitrary number
                        // that should prevent the solid faceter from creating too many extra triangles to sew the surfaces.
                        // We may evaluate this number over time.
                        if ((numberOfTriangles > 0 && numberOfVertices > 0) && (numberOfTriangles < 50000))
                        {
                            IList<IFCAnyHandle> vertexHandles = new List<IFCAnyHandle>();
                            HashSet<IFCAnyHandle> currentFaceSet = new HashSet<IFCAnyHandle>();

                            if (ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView)
                            {
                                List<List<double>> coordList = new List<List<double>>();

                                // create list of vertices first.
                                for (int i = 0; i < numberOfVertices; i++)
                                {
                                    List<double> vertCoord = new List<double>();

                                    XYZ vertex = component.GetVertex(i);
                                    XYZ vertexScaled = ExporterIFCUtils.TransformAndScalePoint(exporterIFC, vertex);
                                    vertCoord.Add(vertexScaled.X);
                                    vertCoord.Add(vertexScaled.Y);
                                    vertCoord.Add(vertexScaled.Z);
                                    coordList.Add(vertCoord);
                                }

                            }
                            else
                            {
                                // create list of vertices first.
                                for (int ii = 0; ii < numberOfVertices; ii++)
                                {
                                    XYZ vertex = component.GetVertex(ii);
                                    XYZ vertexScaled = ExporterIFCUtils.TransformAndScalePoint(exporterIFC, vertex);
                                    IFCAnyHandle vertexHandle = ExporterUtil.CreateCartesianPoint(file, vertexScaled);
                                    vertexHandles.Add(vertexHandle);
                                }

                                if (!ExportPlanarFacetsIfPossible(file, component, vertexHandles, currentFaceSet))
                                {
                                    // Export all of the triangles instead.
                                    for (int ii = 0; ii < numberOfTriangles; ii++)
                                    {
                                        TriangleInShellComponent triangle = component.GetTriangle(ii);
                                        IList<IFCAnyHandle> vertices = new List<IFCAnyHandle>();
                                        vertices.Add(vertexHandles[triangle.VertexIndex0]);
                                        vertices.Add(vertexHandles[triangle.VertexIndex1]);
                                        vertices.Add(vertexHandles[triangle.VertexIndex2]);

                                        IFCAnyHandle face = CreateFaceFromVertexList(file, vertices);
                                        currentFaceSet.Add(face);
                                    }
                                }

                                currentFaceHashSetList.Add(currentFaceSet);
                                exportedAsSolid = true;
                            }
                        }
                    }
                }
                return exportedAsSolid;
            }
            catch
            {
                string errMsg = String.Format("TessellateSolidOrShell failed in IFC export for element \"{0}\" with id {1}", element.Name, element.Id);
                document.Application.WriteJournalComment(errMsg, false/*timestamp*/);
                return false;
            }
        }
Пример #23
0
 /// <summary>
 /// Constructs a copy of a BodyExporterOptions object.
 /// </summary>
 public BodyExporterOptions(BodyExporterOptions options) 
 {
     TryToExportAsExtrusion = options.TryToExportAsExtrusion;
     ExtrusionLocalCoordinateSystem = options.ExtrusionLocalCoordinateSystem;
     TryToExportAsSweptSolid = options.TryToExportAsSweptSolid;
     AllowOffsetTransform = options.AllowOffsetTransform;
     UseMappedGeometriesIfPossible = options.UseMappedGeometriesIfPossible;
     UseGroupsIfPossible = options.UseGroupsIfPossible;
     TessellationControls = options.TessellationControls;
     TessellationLevel = options.TessellationLevel;
 }
Пример #24
0
        /// <summary>
        /// Exports a beam to IFC beam.
        /// </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 ExportBeam(ExporterIFC exporterIFC,
           Element element, GeometryElement geometryElement, ProductWrapper productWrapper)
        {
            if (geometryElement == null)
                return;

            IFCFile file = exporterIFC.GetFile();
            
            using (IFCTransaction transaction = new IFCTransaction(file))
            {
                LocationCurve locCurve = element.Location as LocationCurve;
                Transform orientTrf = Transform.Identity;

                bool canExportAxis = (locCurve != null);
                IFCAnyHandle axisRep = null;

                XYZ beamDirection = null;
                XYZ projDir = null;
                Curve curve = null;

                Plane plane = null;
                if (canExportAxis)
                {
                    curve = locCurve.Curve;
                    if (curve is Line)
                    {
                        Line line = curve as Line;
                        XYZ planeY, planeOrig;
                        planeOrig = line.GetEndPoint(0);
                        beamDirection = line.Direction;
                        if (Math.Abs(beamDirection.Z) < 0.707)  // approx 1.0/sqrt(2.0)
                        {
                            planeY = XYZ.BasisZ.CrossProduct(beamDirection);
                        }
                        else
                        {
                            planeY = XYZ.BasisX.CrossProduct(beamDirection);
                        }
                        planeY = planeY.Normalize();
                        projDir = beamDirection.CrossProduct(planeY);
                        plane = new Plane(beamDirection, planeY, planeOrig);
                        orientTrf.BasisX = beamDirection; orientTrf.BasisY = planeY; orientTrf.BasisZ = projDir; orientTrf.Origin = planeOrig;
                    }
                    else if (curve is Arc)
                    {
                        XYZ yDir, center;
                        Arc arc = curve as Arc;
                        beamDirection = arc.XDirection; yDir = arc.YDirection; projDir = arc.Normal; center = arc.Center;
                        plane = new Plane(beamDirection, yDir, center);
                        orientTrf.BasisX = beamDirection; orientTrf.BasisY = yDir; orientTrf.BasisZ = projDir; orientTrf.Origin = center;
                    }
                    else
                        canExportAxis = false;
                }

                using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element, null, canExportAxis ? orientTrf : null))
                {
                    IFCAnyHandle localPlacement = setter.LocalPlacement;
                    SolidMeshGeometryInfo solidMeshInfo = GeometryUtil.GetSplitSolidMeshGeometry(geometryElement);

                    using (IFCExtrusionCreationData extrusionCreationData = new IFCExtrusionCreationData())
                    {
                        extrusionCreationData.SetLocalPlacement(localPlacement);
                        if (canExportAxis && (orientTrf.BasisX != null))
                        {
                            extrusionCreationData.CustomAxis = beamDirection;
                            extrusionCreationData.PossibleExtrusionAxes = IFCExtrusionAxes.TryCustom;
                        }
                        else
                            extrusionCreationData.PossibleExtrusionAxes = IFCExtrusionAxes.TryXY;

                        IList<Solid> solids = solidMeshInfo.GetSolids();
                        IList<Mesh> meshes = solidMeshInfo.GetMeshes();
                        
                        ElementId catId = CategoryUtil.GetSafeCategoryId(element);

                        // The representation handle generated from one of the methods below.
                        IFCAnyHandle repHnd = null;

                        // The list of materials in the solids or meshes.
                        ICollection<ElementId> materialIds = new HashSet<ElementId>();

                        // There may be an offset to make the local coordinate system
                        // be near the origin.  This offset will be used to move the axis to the new LCS.
                        Transform offsetTransform = null;
                        
                        // If we have a beam with a Linear location line that only has one solid geometry,
                        // we will try to use the ExtrusionAnalyzer to generate an extrusion with 0 or more clippings.
                        // This code is currently limited in that it will not process beams with openings, so we
                        // use other methods below if this one fails.
                        if (solids.Count == 1 && meshes.Count == 0 && (canExportAxis && (curve is Line)))
                        {
                            bool completelyClipped;
                            beamDirection = orientTrf.BasisX;
                            Plane beamExtrusionPlane = new Plane(orientTrf.BasisY, orientTrf.BasisZ, orientTrf.Origin);
                            repHnd = ExtrusionExporter.CreateExtrusionWithClipping(exporterIFC, element,
                                catId, solids[0], beamExtrusionPlane, beamDirection, null, out completelyClipped);
                            if (completelyClipped)
                                return;

                            if (!IFCAnyHandleUtil.IsNullOrHasNoValue(repHnd))
                            {
                                // This is used by the BeamSlopeCalculator.  This should probably be generated automatically by
                                // CreateExtrusionWithClipping.
                                IFCExtrusionBasis bestAxis = (Math.Abs(beamDirection[0]) > Math.Abs(beamDirection[1])) ?
                                    IFCExtrusionBasis.BasisX : IFCExtrusionBasis.BasisY;
                                extrusionCreationData.Slope = GeometryUtil.GetSimpleExtrusionSlope(beamDirection, bestAxis);
                                ElementId materialId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(solids[0], exporterIFC, element);
                                if (materialId != ElementId.InvalidElementId)
                                    materialIds.Add(materialId);
                            }
                        }

                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(repHnd))
                        {
                            BodyData bodyData = null;

                            BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true);
                            if (solids.Count > 0 || meshes.Count > 0)
                            {
                                bodyData = BodyExporter.ExportBody(exporterIFC, element, catId, ElementId.InvalidElementId,
                                    solids, meshes, bodyExporterOptions, extrusionCreationData);
                            }
                            else
                            {
                                IList<GeometryObject> geomlist = new List<GeometryObject>();
                                geomlist.Add(geometryElement);
                                bodyData = BodyExporter.ExportBody(exporterIFC, element, catId, ElementId.InvalidElementId, 
                                    geomlist, bodyExporterOptions, extrusionCreationData);
                            }
                            repHnd = bodyData.RepresentationHnd;
                            materialIds = bodyData.MaterialIds;
                            offsetTransform = bodyData.OffsetTransform;
                        }

                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(repHnd))
                        {
                            extrusionCreationData.ClearOpenings();
                            return;
                        }

                        IList<IFCAnyHandle> representations = new List<IFCAnyHandle>();

                        if (canExportAxis)
                        {
                            XYZ curveOffset = new XYZ(0, 0, 0);
                            if (offsetTransform != null)
                                curveOffset = -UnitUtil.UnscaleLength(offsetTransform.Origin);
                            else
                            {
                                // Note that we do not have to have any scaling adjustment here, since the curve origin is in the 
                                // same internal coordinate system as the curve.
                                curveOffset = -plane.Origin;
                            }

                            Plane offsetPlane = new Plane(plane.XVec, plane.YVec, XYZ.Zero);
                            IFCGeometryInfo info = IFCGeometryInfo.CreateCurveGeometryInfo(exporterIFC, offsetPlane, projDir, false);
                            ExporterIFCUtils.CollectGeometryInfo(exporterIFC, info, curve, curveOffset, true);
                            
                            IList<IFCAnyHandle> axis_items = info.GetCurves();

                            if (axis_items.Count > 0)
                            {
                                string identifierOpt = "Axis";	// this is by IFC2x2 convention, not temporary
                                string representationTypeOpt = "Curve2D";  // this is by IFC2x2 convention, not temporary
                                axisRep = RepresentationUtil.CreateShapeRepresentation(exporterIFC, element, catId, exporterIFC.Get3DContextHandle(identifierOpt),
                                   identifierOpt, representationTypeOpt, axis_items);
                                representations.Add(axisRep);
                            }
                        }
                        representations.Add(repHnd);

                        Transform boundingBoxTrf = (offsetTransform == null) ? Transform.Identity : offsetTransform.Inverse;
                        IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, geometryElement, boundingBoxTrf);
                        if (boundingBoxRep != null)
                            representations.Add(boundingBoxRep);

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

                        string instanceGUID = GUIDUtil.CreateGUID(element);
                        string instanceName = NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element));
                        string instanceDescription = NamingUtil.GetDescriptionOverride(element, null);
                        string instanceObjectType = NamingUtil.GetObjectTypeOverride(element, NamingUtil.CreateIFCObjectName(exporterIFC, element));
                        string instanceTag = NamingUtil.GetTagOverride(element, NamingUtil.CreateIFCElementId(element));
                        string preDefinedType = "BEAM";     // Default predefined type for Beam
                        preDefinedType = IFCValidateEntry.GetValidIFCType (element, preDefinedType);

                        IFCAnyHandle beam = IFCInstanceExporter.CreateBeam(file, instanceGUID, exporterIFC.GetOwnerHistoryHandle(),
                            instanceName, instanceDescription, instanceObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, instanceTag, preDefinedType);

                        productWrapper.AddElement(element, beam, setter, extrusionCreationData, true);

                        OpeningUtil.CreateOpeningsIfNecessary(beam, element, extrusionCreationData, offsetTransform, exporterIFC, 
                            extrusionCreationData.GetLocalPlacement(), setter, productWrapper);

                        FamilyTypeInfo typeInfo = new FamilyTypeInfo();
                        typeInfo.ScaledDepth = extrusionCreationData.ScaledLength;
                        typeInfo.ScaledArea = extrusionCreationData.ScaledArea;
                        typeInfo.ScaledInnerPerimeter = extrusionCreationData.ScaledInnerPerimeter;
                        typeInfo.ScaledOuterPerimeter = extrusionCreationData.ScaledOuterPerimeter;
                        PropertyUtil.CreateBeamColumnBaseQuantities(exporterIFC, beam, element, typeInfo, null);

                        if (materialIds.Count != 0)
                        {
                            CategoryUtil.CreateMaterialAssociations(exporterIFC, beam, materialIds);
                        }

                        // Register the beam's IFC handle for later use by truss and beam system export.
                        ExporterCacheManager.ElementToHandleCache.Register(element.Id, beam);
                    }
                }

                transaction.Commit();
            }
        }
Пример #25
0
        /// <summary>
        /// Exports a Rebar Coupler,
        /// </summary>
        /// <param name="exporterIFC">The exporter.</param>
        /// <param name="coupler">The RebarCoupler element.</param>
        /// <param name="productWrapper">The product wrapper.</param>
        public static void ExportCoupler(ExporterIFC exporterIFC, RebarCoupler coupler, ProductWrapper productWrapper)
        {
            if (coupler == null)
            {
                return;
            }

            FamilySymbol familySymbol = ExporterCacheManager.Document.GetElement(coupler.GetTypeId()) as FamilySymbol;

            if (familySymbol == null)
            {
                return;
            }

            // Check the intended IFC entity or type name is in the exclude list specified in the UI
            Common.Enums.IFCEntityType elementClassTypeEnum = Common.Enums.IFCEntityType.IfcMechanicalFastener;
            if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum))
            {
                return;
            }

            ElementId categoryId = CategoryUtil.GetSafeCategoryId(coupler);

            IFCFile           file         = exporterIFC.GetFile();
            IFCAnyHandle      ownerHistory = ExporterCacheManager.OwnerHistoryHandle;
            Options           options      = GeometryUtil.GetIFCExportGeometryOptions();;
            string            ifcEnumType;
            IFCExportInfoPair exportType = ExporterUtil.GetExportType(exporterIFC, coupler, out ifcEnumType);

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                FamilyTypeInfo currentTypeInfo = ExporterCacheManager.FamilySymbolToTypeInfoCache.Find(coupler.GetTypeId(), false, exportType);
                bool           found           = currentTypeInfo.IsValid();
                if (!found)
                {
                    string typeObjectType = NamingUtil.CreateIFCObjectName(exporterIFC, familySymbol);

                    HashSet <IFCAnyHandle> propertySetsOpt = new HashSet <IFCAnyHandle>();

                    GeometryElement exportGeometry = familySymbol.get_Geometry(options);

                    BodyData            bodyData            = null;
                    BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow);
                    bodyData = BodyExporter.ExportBody(exporterIFC, coupler, categoryId, ElementId.InvalidElementId, exportGeometry, bodyExporterOptions, null);

                    List <IFCAnyHandle> repMap = new List <IFCAnyHandle>();
                    IFCAnyHandle        origin = ExporterUtil.CreateAxis2Placement3D(file);;
                    repMap.Add(IFCInstanceExporter.CreateRepresentationMap(file, origin, bodyData.RepresentationHnd));

                    IFCAnyHandle styleHandle = FamilyExporterUtil.ExportGenericType(exporterIFC, exportType, ifcEnumType, propertySetsOpt, repMap, coupler, familySymbol);
                    productWrapper.RegisterHandleWithElementType(familySymbol, exportType, styleHandle, propertySetsOpt);

                    if (!IFCAnyHandleUtil.IsNullOrHasNoValue(styleHandle))
                    {
                        currentTypeInfo.Style = styleHandle;
                        ExporterCacheManager.FamilySymbolToTypeInfoCache.Register(coupler.GetTypeId(), false, exportType, currentTypeInfo);
                    }
                }

                int nCouplerQuantity = coupler.GetCouplerQuantity();
                if (nCouplerQuantity <= 0)
                {
                    return;
                }

                ISet <IFCAnyHandle> createdRebarCouplerHandles = new HashSet <IFCAnyHandle>();
                string origInstanceName = NamingUtil.GetNameOverride(coupler, NamingUtil.GetIFCName(coupler));

                for (int idx = 0; idx < nCouplerQuantity; idx++)
                {
                    string instanceGUID = GUIDUtil.CreateSubElementGUID(coupler, idx);

                    IFCAnyHandle style = currentTypeInfo.Style;
                    if (IFCAnyHandleUtil.IsNullOrHasNoValue(style))
                    {
                        return;
                    }

                    IList <IFCAnyHandle> repMapList = GeometryUtil.GetRepresentationMaps(style);
                    if (repMapList == null)
                    {
                        return;
                    }
                    if (repMapList.Count == 0)
                    {
                        return;
                    }

                    IList <IFCAnyHandle> shapeReps        = new List <IFCAnyHandle>();
                    IFCAnyHandle         contextOfItems3d = exporterIFC.Get3DContextHandle("Body");
                    ISet <IFCAnyHandle>  representations  = new HashSet <IFCAnyHandle>();
                    representations.Add(ExporterUtil.CreateDefaultMappedItem(file, repMapList[0], XYZ.Zero));
                    IFCAnyHandle shapeRep = RepresentationUtil.CreateBodyMappedItemRep(exporterIFC, coupler, categoryId, contextOfItems3d, representations);
                    shapeReps.Add(shapeRep);

                    IFCAnyHandle productRepresentation = IFCInstanceExporter.CreateProductDefinitionShape(exporterIFC.GetFile(), null, null, shapeReps);

                    Transform trf = coupler.GetCouplerPositionTransform(idx);

                    using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, coupler, trf, null))
                    {
                        IFCAnyHandle      instanceHandle     = null;
                        IFCExportInfoPair exportMechFastener = new IFCExportInfoPair(IFCEntityType.IfcMechanicalFastener, ifcEnumType);
                        instanceHandle = IFCInstanceExporter.CreateGenericIFCEntity(exportMechFastener, exporterIFC, coupler, instanceGUID, ownerHistory,
                                                                                    setter.LocalPlacement, productRepresentation);
                        string instanceName = NamingUtil.GetNameOverride(instanceHandle, coupler, origInstanceName + ": " + idx);
                        IFCAnyHandleUtil.OverrideNameAttribute(instanceHandle, instanceName);

                        if (ExporterCacheManager.ExportOptionsCache.ExportAs4)
                        {
                            // In IFC4 NominalDiameter and NominalLength attributes have been deprecated. PredefinedType attribute was added.
                            IFCAnyHandleUtil.SetAttribute(instanceHandle, "PredefinedType", Revit.IFC.Export.Toolkit.IFC4.IFCMechanicalFastenerType.USERDEFINED);
                        }
                        else
                        {
                            IFCAnyHandleUtil.SetAttribute(instanceHandle, "NominalDiameter", familySymbol.get_Parameter(BuiltInParameter.COUPLER_WIDTH).AsDouble());
                            IFCAnyHandleUtil.SetAttribute(instanceHandle, "NominalLength", familySymbol.get_Parameter(BuiltInParameter.COUPLER_LENGTH).AsDouble());
                        }

                        createdRebarCouplerHandles.Add(instanceHandle);

                        productWrapper.AddElement(coupler, instanceHandle, setter, null, true, exportType);
                    }
                }

                string couplerGUID = GUIDUtil.CreateGUID(coupler);

                if (nCouplerQuantity > 1)
                {
                    // Create a group to hold all of the created IFC entities, if the coupler aren't already in an assembly.
                    // We want to avoid nested groups of groups of couplers.
                    if (coupler.AssemblyInstanceId == ElementId.InvalidElementId)
                    {
                        string revitObjectType = NamingUtil.GetFamilyAndTypeName(coupler);
                        string name            = NamingUtil.GetNameOverride(coupler, revitObjectType);
                        string description     = NamingUtil.GetDescriptionOverride(coupler, null);
                        string objectType      = NamingUtil.GetObjectTypeOverride(coupler, revitObjectType);

                        IFCAnyHandle rebarGroup = IFCInstanceExporter.CreateGroup(file, couplerGUID,
                                                                                  ownerHistory, name, description, objectType);

                        productWrapper.AddElement(coupler, rebarGroup, exportType);

                        IFCInstanceExporter.CreateRelAssignsToGroup(file, GUIDUtil.CreateGUID(), ownerHistory,
                                                                    null, null, createdRebarCouplerHandles, null, rebarGroup);
                    }
                }
                else
                {
                    // We will update the GUID of the one created element to be the element GUID.
                    // This will allow the IfcGUID parameter to be use/set if appropriate.
                    ExporterUtil.SetGlobalId(createdRebarCouplerHandles.ElementAt(0), couplerGUID);
                }

                tr.Commit();
            }
        }
Пример #26
0
        /// <summary>
        /// Exports an element to IFC footing.
        /// </summary>
        /// <param name="exporterIFC">
        /// The ExporterIFC object.
        /// </param>
        /// <param name="element">
        /// The element.
        /// </param>
        /// <param name="geometryElement">
        /// The geometry element.
        /// </param>
        /// <param name="ifcEnumType">
        /// The string value represents the IFC type.
        /// </param>
        /// <param name="productWrapper">
        /// The ProductWrapper.
        /// </param>
        public static void ExportFooting(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement,
                                         string ifcEnumType, ProductWrapper productWrapper)
        {
            // export parts or not
            bool exportParts = PartExporter.CanExportParts(element);

            if (exportParts && !PartExporter.CanExportElementInPartExport(element, element.LevelId, false))
            {
                return;
            }

            // Check the intended IFC entity or type name is in the exclude list specified in the UI
            Common.Enums.IFCEntityType elementClassTypeEnum = Common.Enums.IFCEntityType.IfcFooting;
            if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum))
            {
                return;
            }

            IFCFile file = exporterIFC.GetFile();

            using (IFCTransaction tr = 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())
                    {
                        ecData.SetLocalPlacement(setter.LocalPlacement);

                        IFCAnyHandle prodRep = null;
                        ElementId    matId   = ElementId.InvalidElementId;
                        if (!exportParts)
                        {
                            ElementId catId = CategoryUtil.GetSafeCategoryId(element);


                            matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geometryElement, exporterIFC, element);
                            BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow);
                            prodRep = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC,
                                                                                                 element, catId, geometryElement, bodyExporterOptions, null, ecData, true);
                            if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodRep))
                            {
                                ecData.ClearOpenings();
                                return;
                            }
                        }

                        string instanceGUID = GUIDUtil.CreateGUID(element);

                        string            footingType = GetIFCFootingType(ifcEnumType); // need to keep it for legacy support when original data follows slightly diff naming
                        IFCExportInfoPair exportInfo  = new IFCExportInfoPair(elementClassTypeEnum, footingType);

                        IFCAnyHandle footing = IFCInstanceExporter.CreateFooting(exporterIFC, element, instanceGUID, ExporterCacheManager.OwnerHistoryHandle,
                                                                                 ecData.GetLocalPlacement(), prodRep, footingType);

                        // TODO: to allow shared geometry for Footings. For now, Footing export will not use shared geometry
                        if (exportInfo.ExportType != Common.Enums.IFCEntityType.UnKnown)
                        {
                            IFCAnyHandle type = ExporterUtil.CreateGenericTypeFromElement(element, exportInfo, file, ExporterCacheManager.OwnerHistoryHandle, exportInfo.ValidatedPredefinedType, productWrapper);
                            ExporterCacheManager.TypeRelationsCache.Add(type, footing);
                        }

                        if (exportParts)
                        {
                            PartExporter.ExportHostPart(exporterIFC, element, footing, productWrapper, setter, setter.LocalPlacement, null);
                        }
                        else
                        {
                            if (matId != ElementId.InvalidElementId)
                            {
                                CategoryUtil.CreateMaterialAssociation(exporterIFC, footing, matId);
                            }
                        }

                        productWrapper.AddElement(element, footing, setter, ecData, true, exportInfo);

                        OpeningUtil.CreateOpeningsIfNecessary(footing, element, ecData, null,
                                                              exporterIFC, ecData.GetLocalPlacement(), setter, productWrapper);
                    }
                }

                tr.Commit();
            }
        }
Пример #27
0
        // NOTE: the useMappedGeometriesIfPossible and useGroupsIfPossible options are experimental and do not yet work well.
        // In shipped code, these are always false, and should be kept false until API support routines are proved to be reliable.
        private static BodyData ExportBodyAsBRep(ExporterIFC exporterIFC, IList<GeometryObject> splitGeometryList,
            IList<KeyValuePair<int, SimpleSweptSolidAnalyzer>> exportAsBRep, IList<IFCAnyHandle> bodyItems,
            Element element, ElementId categoryId, ElementId overrideMaterialId, IFCAnyHandle contextOfItems, double eps,
            BodyExporterOptions options, BodyData bodyDataIn)
        {
            bool exportAsBReps = true;
            bool hasTriangulatedGeometry = false;
            bool hasAdvancedBrepGeometry = false;
            IFCFile file = exporterIFC.GetFile();
            Document document = element.Document;

            // Can't use the optimization functions below if we already have partially populated our body items with extrusions.
            int numExtrusions = bodyItems.Count;
            bool useMappedGeometriesIfPossible = options.UseMappedGeometriesIfPossible && (numExtrusions != 0);
            bool useGroupsIfPossible = options.UseGroupsIfPossible && (numExtrusions != 0);

            IList<HashSet<IFCAnyHandle>> currentFaceHashSetList = new List<HashSet<IFCAnyHandle>>();
            IList<int> startIndexForObject = new List<int>();

            BodyData bodyData = new BodyData(bodyDataIn);

            IDictionary<SolidMetrics, HashSet<Solid>> solidMappingGroups = null;
            IList<KeyValuePair<int, Transform>> solidMappings = null;
            IList<ElementId> materialIds = new List<ElementId>();

            // This should currently be always false in shipped code.
            if (useMappedGeometriesIfPossible)
            {
                IList<GeometryObject> newGeometryList = null;
                useMappedGeometriesIfPossible = GatherMappedGeometryGroupings(splitGeometryList, out newGeometryList, out solidMappingGroups, out solidMappings);
                if (useMappedGeometriesIfPossible && (newGeometryList != null))
                    splitGeometryList = newGeometryList;
            }

            BodyGroupKey groupKey = null;
            BodyGroupData groupData = null;
            // This should currently be always false in shipped code.
            if (useGroupsIfPossible)
            {
                BodyData bodyDataOut = null;
                useGroupsIfPossible = ProcessGroupMembership(exporterIFC, file, element, categoryId, contextOfItems, splitGeometryList, bodyData,
                    out groupKey, out groupData, out bodyDataOut);
                if (bodyDataOut != null)
                    return bodyDataOut;
                if (useGroupsIfPossible)
                    useMappedGeometriesIfPossible = true;
            }

            bool isCoarse = (options.TessellationLevel == BodyExporterOptions.BodyTessellationLevel.Coarse);

            int numBRepsToExport = exportAsBRep.Count;
            bool selectiveBRepExport = (numBRepsToExport > 0);
            int numGeoms = selectiveBRepExport ? numBRepsToExport : splitGeometryList.Count;

            bool canExportAsAdvancedGeometry = ExporterCacheManager.ExportOptionsCache.ExportAs4DesignTransferView;
            bool canExportAsTessellatedFaceSet = ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView;

            // We will cycle through all of the geometries one at a time, doing the best export we can for each.
            for (int index = 0; index < numGeoms; index++)
            {
                int brepIndex = selectiveBRepExport ? exportAsBRep[index].Key : index;
                SimpleSweptSolidAnalyzer currAnalyzer = selectiveBRepExport ? exportAsBRep[index].Value : null;

                GeometryObject geomObject = selectiveBRepExport ? splitGeometryList[brepIndex] : splitGeometryList[index];

                // A simple test to see if the geometry is a valid solid.  This will save a lot of time in CanCreateClosedShell later.
                if (exportAsBReps && (geomObject is Solid))
                {
                    try
                    {
                        // We don't care what the value is here.  What we care about is whether or not it can be calculated.  If it can't be calculated,
                        // it is probably not a valid solid.
                        double volume = (geomObject as Solid).Volume;

                        // Current code should already prevent 0 volume solids from coming here, but may as well play it safe.
                        if (volume <= MathUtil.Eps())
                            exportAsBReps = false;
                    }
                    catch
                    {
                        exportAsBReps = false;
                    }
                }

                startIndexForObject.Add(currentFaceHashSetList.Count);

                ElementId materialId = SetBestMaterialIdInExporter(geomObject, element, overrideMaterialId, exporterIFC);
                materialIds.Add(materialId);
                bodyData.AddMaterial(materialId);

                bool alreadyExported = false;

                // First, see if this could be represented as a simple swept solid.
                if (exportAsBReps && (currAnalyzer != null))
                {
                    SweptSolidExporter sweptSolidExporter = SweptSolidExporter.Create(exporterIFC, element, currAnalyzer, geomObject);
                    HashSet<IFCAnyHandle> facetHnds = (sweptSolidExporter != null) ? sweptSolidExporter.Facets : null;
                    if (facetHnds != null && facetHnds.Count != 0)
                    {
                        currentFaceHashSetList.Add(facetHnds);
                        alreadyExported = true;
                    }
                }

                // Next, try to represent as an AdvancedBRep.
                if (!alreadyExported && canExportAsAdvancedGeometry)
                {
                    IFCAnyHandle advancedBrepBodyItem = ExportBodyAsAdvancedBrep(exporterIFC, element, options, geomObject);
                    if (!IFCAnyHandleUtil.IsNullOrHasNoValue(advancedBrepBodyItem))
                    {
                        bodyItems.Add(advancedBrepBodyItem);
                        alreadyExported = true;
                        hasAdvancedBrepGeometry = true;
                    }
                }

                // If we are using the Reference View, try a triangulated face set.
                // In theory, we could export a tessellated face set for geometry in the Design Transfer View that failed above.
                // However, FacetedBReps do hold more information (and aren't only triangles).
                if (!alreadyExported && canExportAsTessellatedFaceSet)
                {
                    IFCAnyHandle triangulatedBodyItem = ExportBodyAsTriangulatedFaceSet(exporterIFC, element, options, geomObject);
                    if (!IFCAnyHandleUtil.IsNullOrHasNoValue(triangulatedBodyItem))
                    {
                        bodyItems.Add(triangulatedBodyItem);
                        alreadyExported = true;
                        hasTriangulatedGeometry = true;
                    }

                    // We should log here that we couldn't export a geometry.  We aren't allowed to use the traditional methods below.
                    if (!alreadyExported)
                        continue;
                }

                // If the above options do not generate any body, do the traditional step for Brep
                if (!alreadyExported && (exportAsBReps || isCoarse))
                    alreadyExported = ExportBodyAsSolid(exporterIFC, element, options, currentFaceHashSetList, geomObject);

                // If all else fails, use the internal routine to go through the faces.  This will likely create a surface model.
                if (!alreadyExported)
                {
                    IFCGeometryInfo faceListInfo = IFCGeometryInfo.CreateFaceGeometryInfo(eps, isCoarse);
                    ExporterIFCUtils.CollectGeometryInfo(exporterIFC, faceListInfo, geomObject, XYZ.Zero, false);

                    IList<ICollection<IFCAnyHandle>> faceSetList = faceListInfo.GetFaces();

                    int numBReps = faceSetList.Count;
                    if (numBReps == 0)
                        continue;

                    foreach (ICollection<IFCAnyHandle> currentFaceSet in faceSetList)
                    {
                        if (currentFaceSet.Count == 0)
                            continue;

                        if (exportAsBReps)
                        {
                            bool canExportAsClosedShell = (currentFaceSet.Count >= 4);
                            if (canExportAsClosedShell)
                            {
                                if ((geomObject is Mesh) && (numBReps == 1))
                                {
                                    // use optimized version.
                                    canExportAsClosedShell = CanCreateClosedShell(geomObject as Mesh);
                                }
                                else
                                {
                                    canExportAsClosedShell = CanCreateClosedShell(currentFaceSet);
                                }
                            }

                            if (!canExportAsClosedShell)
                            {
                                exportAsBReps = false;

                                // We'll need to invalidate the extrusions we created and replace them with BReps.
                                if (selectiveBRepExport && (numGeoms != splitGeometryList.Count))
                                {
                                    for (int fixIndex = 0; fixIndex < numExtrusions; fixIndex++)
                                    {
                                        bodyItems[0].Delete();
                                        bodyItems.RemoveAt(0);
                                    }
                                    numExtrusions = 0;
                                    numGeoms = splitGeometryList.Count;
                                    int currBRepIndex = 0;
                                    for (int fixIndex = 0; fixIndex < numGeoms; fixIndex++)
                                    {
                                        bool outOfRange = (currBRepIndex >= numBRepsToExport);
                                        if (!outOfRange && (exportAsBRep[currBRepIndex].Key == fixIndex))
                                        {
                                            currBRepIndex++;
                                            continue;
                                        }
                                        SimpleSweptSolidAnalyzer fixAnalyzer = outOfRange ? null : exportAsBRep[currBRepIndex].Value;
                                        exportAsBRep.Add(new KeyValuePair<int, SimpleSweptSolidAnalyzer>(fixIndex, fixAnalyzer));
                                    }
                                    numBRepsToExport = exportAsBRep.Count;
                                }
                            }
                        }

                        currentFaceHashSetList.Add(new HashSet<IFCAnyHandle>(currentFaceSet));
                    }
                }
            }

            if (hasTriangulatedGeometry)
            {
                HashSet<IFCAnyHandle> bodyItemSet = new HashSet<IFCAnyHandle>();
                bodyItemSet.UnionWith(bodyItems);
                if (bodyItemSet.Count > 0)
                {
                    bodyData.RepresentationHnd = RepresentationUtil.CreateTessellatedRep(exporterIFC, element, categoryId, contextOfItems, bodyItemSet, null);
                    bodyData.ShapeRepresentationType = ShapeRepresentationType.Tessellation;
                }
            }
            else if (hasAdvancedBrepGeometry)
            {
                HashSet<IFCAnyHandle> bodyItemSet = new HashSet<IFCAnyHandle>();
                bodyItemSet.UnionWith(bodyItems);
                if (bodyItemSet.Count > 0)
                {
                    bodyData.RepresentationHnd = RepresentationUtil.CreateAdvancedBRepRep(exporterIFC, element, categoryId, contextOfItems, bodyItemSet, null);
                    bodyData.ShapeRepresentationType = ShapeRepresentationType.AdvancedBrep;
                }
            }
            else
            {
                startIndexForObject.Add(currentFaceHashSetList.Count);  // end index for last object.

                IList<IFCAnyHandle> repMapItems = new List<IFCAnyHandle>();

                int size = currentFaceHashSetList.Count;
                if (exportAsBReps)
                {
                    int matToUse = -1;
                    for (int ii = 0; ii < size; ii++)
                    {
                        if (startIndexForObject[matToUse + 1] == ii)
                            matToUse++;
                        HashSet<IFCAnyHandle> currentFaceHashSet = currentFaceHashSetList[ii];
                        ElementId currMatId = materialIds[matToUse];

                        IFCAnyHandle faceOuter = IFCInstanceExporter.CreateClosedShell(file, currentFaceHashSet);
                        IFCAnyHandle brepHnd = RepresentationUtil.CreateFacetedBRep(exporterIFC, document, faceOuter, currMatId);

                        if (!IFCAnyHandleUtil.IsNullOrHasNoValue(brepHnd))
                        {
                            if (useMappedGeometriesIfPossible)
                            {
                                IFCAnyHandle currMappedRepHnd = CreateBRepRepresentationMap(exporterIFC, file, element, categoryId, contextOfItems, brepHnd);
                                repMapItems.Add(currMappedRepHnd);

                                IFCAnyHandle mappedItemHnd = ExporterUtil.CreateDefaultMappedItem(file, currMappedRepHnd);
                                bodyItems.Add(mappedItemHnd);
                            }
                            else
                                bodyItems.Add(brepHnd);
                        }
                    }
                }
                else
                {
                    IDictionary<ElementId, HashSet<IFCAnyHandle>> faceSets = new Dictionary<ElementId, HashSet<IFCAnyHandle>>();
                    int matToUse = -1;
                    for (int ii = 0; ii < size; ii++)
                    {
                        HashSet<IFCAnyHandle> currentFaceHashSet = currentFaceHashSetList[ii];
                        if (startIndexForObject[matToUse + 1] == ii)
                            matToUse++;

                        IFCAnyHandle faceSetHnd = IFCInstanceExporter.CreateConnectedFaceSet(file, currentFaceHashSet);
                        if (useMappedGeometriesIfPossible)
                        {
                            IFCAnyHandle currMappedRepHnd = CreateSurfaceRepresentationMap(exporterIFC, file, element, categoryId, contextOfItems, faceSetHnd);
                            repMapItems.Add(currMappedRepHnd);

                            IFCAnyHandle mappedItemHnd = ExporterUtil.CreateDefaultMappedItem(file, currMappedRepHnd);
                            bodyItems.Add(mappedItemHnd);
                        }
                        else
                        {
                            HashSet<IFCAnyHandle> surfaceSet = null;
                            if (faceSets.TryGetValue(materialIds[matToUse], out surfaceSet))
                            {
                                surfaceSet.Add(faceSetHnd);
                            }
                            else
                            {
                                surfaceSet = new HashSet<IFCAnyHandle>();
                                surfaceSet.Add(faceSetHnd);
                                faceSets[materialIds[matToUse]] = surfaceSet;
                            }
                        }
                    }

                    if (faceSets.Count > 0)
                    {
                        foreach (KeyValuePair<ElementId, HashSet<IFCAnyHandle>> faceSet in faceSets)
                        {
                            IFCAnyHandle surfaceModel = IFCInstanceExporter.CreateFaceBasedSurfaceModel(file, faceSet.Value);
                            BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, document, surfaceModel, faceSet.Key);

                            bodyItems.Add(surfaceModel);
                        }
                    }
                }

                if (bodyItems.Count == 0)
                    return bodyData;

                // Add in mapped items.
                if (useMappedGeometriesIfPossible && (solidMappings != null))
                {
                    foreach (KeyValuePair<int, Transform> mappedItem in solidMappings)
                    {
                        for (int idx = startIndexForObject[mappedItem.Key]; idx < startIndexForObject[mappedItem.Key + 1]; idx++)
                        {
                            IFCAnyHandle mappedItemHnd = ExporterUtil.CreateMappedItemFromTransform(file, repMapItems[idx], mappedItem.Value);
                            bodyItems.Add(mappedItemHnd);
                        }
                    }
                }

                HashSet<IFCAnyHandle> bodyItemSet = new HashSet<IFCAnyHandle>();
                bodyItemSet.UnionWith(bodyItems);
                if (useMappedGeometriesIfPossible)
                {
                    bodyData.RepresentationHnd = RepresentationUtil.CreateBodyMappedItemRep(exporterIFC, element, categoryId, contextOfItems, bodyItemSet);
                }
                else if (exportAsBReps)
                {
                    if (numExtrusions > 0)
                        bodyData.RepresentationHnd = RepresentationUtil.CreateSolidModelRep(exporterIFC, element, categoryId, contextOfItems, bodyItemSet);
                    else
                        bodyData.RepresentationHnd = RepresentationUtil.CreateBRepRep(exporterIFC, element, categoryId, contextOfItems, bodyItemSet);
                }
                else
                    bodyData.RepresentationHnd = RepresentationUtil.CreateSurfaceRep(exporterIFC, element, categoryId, contextOfItems, bodyItemSet, false, null);

                if (useGroupsIfPossible && (groupKey != null) && (groupData != null))
                {
                    groupData.Handles = repMapItems;
                    ExporterCacheManager.GroupElementGeometryCache.Register(groupKey, groupData);
                }

                bodyData.ShapeRepresentationType = ShapeRepresentationType.Brep;
            }

            return bodyData;
        }
Пример #28
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);

                        IFCAnyHandle railing = IFCInstanceExporter.CreateRailing(exporterIFC, element, instanceGUID, ownerHistory,
                                                                                 ecData.GetLocalPlacement(), prodRep, ifcEnumType);
                        IFCExportInfoPair exportInfo = new IFCExportInfoPair(elementClassTypeEnum, ifcEnumType);
                        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);

                        CategoryUtil.CreateMaterialAssociation(exporterIFC, railing, bodyData.MaterialIds);

                        // 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.CreateMaterialAssociation(exporterIFC, railingHndCopy, bodyData.MaterialIds);
                                }
                            }

                            ExporterCacheManager.StairRampContainerInfoCache.AddStairRampContainerInfo(hostId, stairRampInfo);
                        }
                    }
                    transaction.Commit();
                }
            }
        }
        /// <summary>
        /// Exports a geometry element to boundary representation.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="element">The element.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="exportBoundaryRep">True if to export boundary representation.</param>
        /// <param name="exportAsFacetation">True if to export the geometry as facetation.</param>
        /// <param name="bodyRep">Body representation.</param>
        /// <param name="boundaryRep">Boundary representation.</param>
        /// <returns>True if success, false if fail.</returns>
        public static bool ExportSurface(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement,
           bool exportBoundaryRep, bool exportAsFacetation, ref IFCAnyHandle bodyRep, ref IFCAnyHandle boundaryRep)
        {
            if (geometryElement == null)
                return false;

            IFCGeometryInfo ifcGeomInfo = null;
            Document doc = element.Document;
            Plane plane = GeometryUtil.CreateDefaultPlane();
            XYZ projDir = new XYZ(0, 0, 1);
            double eps = UnitUtil.ScaleLength(doc.Application.VertexTolerance);

            ifcGeomInfo = IFCGeometryInfo.CreateFaceGeometryInfo(exporterIFC, plane, projDir, eps, exportBoundaryRep);

            ExporterIFCUtils.CollectGeometryInfo(exporterIFC, ifcGeomInfo, geometryElement, XYZ.Zero, true);

            IFCFile file = exporterIFC.GetFile();
            IFCAnyHandle surface;

            // Use tessellated geometry for surface in IFC Reference View
            if (ExporterUtil.IsReferenceView())
            {
                BodyExporterOptions options = new BodyExporterOptions(false);
                surface = BodyExporter.ExportBodyAsTriangulatedFaceSet(exporterIFC, element, options, geometryElement);
            }
            else
            {
                HashSet<IFCAnyHandle> faceSets = new HashSet<IFCAnyHandle>();
                IList<ICollection<IFCAnyHandle>> faceList = ifcGeomInfo.GetFaces();
                foreach (ICollection<IFCAnyHandle> faces in faceList)
                {
                    // no faces, don't complain.
                    if (faces.Count == 0)
                        continue;
                    HashSet<IFCAnyHandle> faceSet = new HashSet<IFCAnyHandle>(faces);
                    faceSets.Add(IFCInstanceExporter.CreateConnectedFaceSet(file, faceSet));
                }

                if (faceSets.Count == 0)
                    return false;

                surface = IFCInstanceExporter.CreateFaceBasedSurfaceModel(file, faceSets);
            }

            if (IFCAnyHandleUtil.IsNullOrHasNoValue(surface))
                return false;

            BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, doc, surface, BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geometryElement, exporterIFC, element));

            ISet<IFCAnyHandle> surfaceItems = new HashSet<IFCAnyHandle>();
            surfaceItems.Add(surface);

            ElementId catId = CategoryUtil.GetSafeCategoryId(element);

            bodyRep = RepresentationUtil.CreateSurfaceRep(exporterIFC, element, catId, exporterIFC.Get3DContextHandle("Body"), surfaceItems, 
                exportAsFacetation, bodyRep);
            if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep))
                return false;

            ICollection<IFCAnyHandle> boundaryRepresentations = ifcGeomInfo.GetRepresentations();
            if (exportBoundaryRep && boundaryRepresentations.Count > 0)
            {
                HashSet<IFCAnyHandle> boundaryRepresentationSet = new HashSet<IFCAnyHandle>();
                boundaryRepresentationSet.UnionWith(boundaryRepresentations);
                boundaryRep = RepresentationUtil.CreateBoundaryRep(exporterIFC, element, catId, exporterIFC.Get3DContextHandle("FootPrint"), boundaryRepresentationSet, 
                    boundaryRep);
            }

            return true;
        }
Пример #30
0
        /// <summary>
        /// Exports list of geometries to IFC body representation.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="categoryId">The category id.</param>
        /// <param name="geometryListIn">The geometry list.</param>
        /// <param name="options">The settings for how to export the body.</param>
        /// <param name="exportBodyParams">The extrusion creation data.</param>
        /// <returns>The BodyData containing the handle, offset and material ids.</returns>
        public static BodyData ExportBody(ExporterIFC exporterIFC,
            Element element,
            ElementId categoryId,
            ElementId overrideMaterialId,
            IList<GeometryObject> geometryList,
            BodyExporterOptions options,
            IFCExtrusionCreationData exportBodyParams)
        {
            BodyData bodyData = new BodyData();
            if (geometryList.Count == 0)
                return bodyData;

            Document document = element.Document;
            bool tryToExportAsExtrusion = options.TryToExportAsExtrusion;
            bool canExportSolidModelRep = tryToExportAsExtrusion && ExporterCacheManager.ExportOptionsCache.CanExportSolidModelRep;

            bool useCoarseTessellation = (ExporterCacheManager.ExportOptionsCache.LevelOfDetail < 4);
            bool allowAdvancedBReps = ExporterCacheManager.ExportOptionsCache.ExportAs4 && !ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView;

            // We will try to export as a swept solid if the option is set, and we are either exporting to a schema that allows it,
            // or we are using a coarse tessellation, in which case we will export the swept solid as an optimzed BRep.
            bool tryToExportAsSweptSolid = options.TryToExportAsSweptSolid && (allowAdvancedBReps || useCoarseTessellation);

            // We will allow exporting swept solids as BReps or TriangulatedFaceSet if we are exporting to a schema before IFC4, or to a Reference View MVD, 
            // and we allow coarse representations.  In the future, we may allow more control here.
            // Note that we disable IFC4 because in IFC4, we will export it as a true swept solid instead, except for the Reference View MVD.
            bool tryToExportAsSweptSolidAsTessellation = tryToExportAsSweptSolid && useCoarseTessellation && !allowAdvancedBReps;

            IFCFile file = exporterIFC.GetFile();
            IFCAnyHandle contextOfItems = exporterIFC.Get3DContextHandle("Body");

            double eps = UnitUtil.ScaleLength(element.Document.Application.VertexTolerance);

            bool allFaces = true;
            foreach (GeometryObject geomObject in geometryList)
            {
                if (!(geomObject is Face))
                {
                    allFaces = false;
                    break;
                }
            }

            IList<IFCAnyHandle> bodyItems = new List<IFCAnyHandle>();
            IList<ElementId> materialIdsForExtrusions = new List<ElementId>();

            // This is a list of geometries that can be exported using the coarse facetation of the SweptSolidExporter.
            IList<KeyValuePair<int, SimpleSweptSolidAnalyzer>> exportAsBRep = new List<KeyValuePair<int, SimpleSweptSolidAnalyzer>>();

            IList<int> exportAsSweptSolid = new List<int>();
            IList<int> exportAsExtrusion = new List<int>();

            bool hasExtrusions = false;
            bool hasSweptSolids = false;
            bool hasSweptSolidsAsBReps = false;
            ShapeRepresentationType hasRepresentationType = ShapeRepresentationType.Undefined;

            BoundingBoxXYZ bbox = GeometryUtil.GetBBoxOfGeometries(geometryList);
            XYZ unscaledTrfOrig = new XYZ();

            int numItems = geometryList.Count;
            bool tryExtrusionAnalyzer = tryToExportAsExtrusion && (options.ExtrusionLocalCoordinateSystem != null) && (numItems == 1) && (geometryList[0] is Solid);
            bool supportOffsetTransformForExtrusions = !(tryExtrusionAnalyzer || tryToExportAsSweptSolidAsTessellation);
            bool useOffsetTransformForExtrusions = (options.AllowOffsetTransform && supportOffsetTransformForExtrusions && (exportBodyParams != null));

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                // generate "bottom corner" of bbox; create new local placement if passed in.
                // need to transform, but not scale, this point to make it the new origin.
                using (TransformSetter transformSetter = TransformSetter.Create())
                {
                    if (useOffsetTransformForExtrusions)
                        bodyData.OffsetTransform = transformSetter.InitializeFromBoundingBox(exporterIFC, bbox, exportBodyParams, out unscaledTrfOrig);

                    // If we passed in an ExtrusionLocalCoordinateSystem, and we have 1 Solid, we will try to create an extrusion using the ExtrusionAnalyzer.
                    // If we succeed, we will skip the rest of the routine, otherwise we will try with the backup extrusion method.
                    // This doesn't yet create fallback information for solid models that are hybrid extrusions and BReps.
                    if (tryToExportAsExtrusion)
                    {
                        if (tryExtrusionAnalyzer)
                        {
                            using (IFCTransaction extrusionTransaction = new IFCTransaction(file))
                            {
                                Plane extrusionPlane = new Plane(
                                        options.ExtrusionLocalCoordinateSystem.BasisY,
                                        options.ExtrusionLocalCoordinateSystem.BasisZ,
                                        options.ExtrusionLocalCoordinateSystem.Origin);
                                XYZ extrusionDirection = options.ExtrusionLocalCoordinateSystem.BasisX;

                                bool completelyClipped;
                                HandleAndData extrusionData = ExtrusionExporter.CreateExtrusionWithClippingAndProperties(exporterIFC, element,
                                    CategoryUtil.GetSafeCategoryId(element), geometryList[0] as Solid, extrusionPlane,
                                    extrusionDirection, null, out completelyClipped);
                                if (!completelyClipped && !IFCAnyHandleUtil.IsNullOrHasNoValue(extrusionData.Handle) && extrusionData.BaseExtrusions != null && extrusionData.BaseExtrusions.Count == 1)
                                {
                                    HashSet<ElementId> materialIds = extrusionData.MaterialIds;

                                    // We skip setting and getting the material id from the exporter as unnecessary.
                                    ElementId matIdFromGeom = (materialIds != null && materialIds.Count > 0) ? materialIds.First() : ElementId.InvalidElementId;
                                    ElementId matId = (overrideMaterialId != ElementId.InvalidElementId) ? overrideMaterialId : matIdFromGeom;

                                    bodyItems.Add(extrusionData.BaseExtrusions[0]);
                                    materialIdsForExtrusions.Add(matId);
                                    if (matId != ElementId.InvalidElementId)
                                        bodyData.AddMaterial(matId);
                                    bodyData.RepresentationHnd = extrusionData.Handle;
                                    bodyData.ShapeRepresentationType = extrusionData.ShapeRepresentationType;

                                    if (exportBodyParams != null && extrusionData.Data != null)
                                    {
                                        exportBodyParams.Slope = extrusionData.Data.Slope;
                                        exportBodyParams.ScaledLength = extrusionData.Data.ScaledLength;
                                        exportBodyParams.ExtrusionDirection = extrusionData.Data.ExtrusionDirection;

                                        exportBodyParams.ScaledHeight = extrusionData.Data.ScaledHeight;
                                        exportBodyParams.ScaledWidth = extrusionData.Data.ScaledWidth;

                                        exportBodyParams.ScaledArea = extrusionData.Data.ScaledArea;
                                        exportBodyParams.ScaledInnerPerimeter = extrusionData.Data.ScaledInnerPerimeter;
                                        exportBodyParams.ScaledOuterPerimeter = extrusionData.Data.ScaledOuterPerimeter;
                                    }

                                    hasExtrusions = true;
                                    extrusionTransaction.Commit();
                                }
                                else
                                {
                                    extrusionTransaction.RollBack();
                                }
                            }
                        }

                        // Only try if ExtrusionAnalyzer wasn't called, or failed.
                        if (!hasExtrusions)
                        {
                            // Check to see if we have Geometries or GFaces.
                            // We will have the specific all GFaces case and then the generic case.
                            IList<Face> faces = null;

                            if (allFaces)
                            {
                                faces = new List<Face>();
                                foreach (GeometryObject geometryObject in geometryList)
                                {
                                    faces.Add(geometryObject as Face);
                                }
                            }

                            // Options used if we try to export extrusions.
                            IFCExtrusionAxes axesToExtrudeIn = exportBodyParams != null ? exportBodyParams.PossibleExtrusionAxes : IFCExtrusionAxes.TryDefault;
                            XYZ directionToExtrudeIn = XYZ.Zero;
                            if (exportBodyParams != null && exportBodyParams.HasCustomAxis)
                                directionToExtrudeIn = exportBodyParams.CustomAxis;

                            double lengthScale = UnitUtil.ScaleLengthForRevitAPI();
                            IFCExtrusionCalculatorOptions extrusionOptions =
                               new IFCExtrusionCalculatorOptions(exporterIFC, axesToExtrudeIn, directionToExtrudeIn, lengthScale);

                            int numExtrusionsToCreate = allFaces ? 1 : geometryList.Count;

                            IList<IList<IFCExtrusionData>> extrusionLists = new List<IList<IFCExtrusionData>>();
                            for (int ii = 0; ii < numExtrusionsToCreate; ii++)
                            {
                                IList<IFCExtrusionData> extrusionList = new List<IFCExtrusionData>();

                                if (tryToExportAsExtrusion)
                                {
                                    if (allFaces)
                                        extrusionList = IFCExtrusionCalculatorUtils.CalculateExtrusionData(extrusionOptions, faces);
                                    else
                                        extrusionList = IFCExtrusionCalculatorUtils.CalculateExtrusionData(extrusionOptions, geometryList[ii]);
                                }

                                if (extrusionList.Count == 0)
                                {
                                    // If we are trying to create swept solids, we will keep going, but we won't try to create more extrusions unless we are also exporting a solid model.
                                    if (tryToExportAsSweptSolid)
                                    {
                                        if (!canExportSolidModelRep)
                                            tryToExportAsExtrusion = false;
                                        exportAsSweptSolid.Add(ii);
                                    }
                                    else if (!canExportSolidModelRep)
                                    {
                                        tryToExportAsExtrusion = false;
                                        break;
                                    }
                                    else
                                        exportAsBRep.Add(new KeyValuePair<int, SimpleSweptSolidAnalyzer>(ii, null));
                                }
                                else
                                {
                                    extrusionLists.Add(extrusionList);
                                    exportAsExtrusion.Add(ii);
                                }
                            }

                            int numCreatedExtrusions = extrusionLists.Count;
                            for (int ii = 0; ii < numCreatedExtrusions && tryToExportAsExtrusion; ii++)
                            {
                                int geomIndex = exportAsExtrusion[ii];

                                ElementId matId = SetBestMaterialIdInExporter(geometryList[geomIndex], element, overrideMaterialId, exporterIFC);
                                if (matId != ElementId.InvalidElementId)
                                    bodyData.AddMaterial(matId);

                                if (exportBodyParams != null && exportBodyParams.AreInnerRegionsOpenings)
                                {
                                    IList<CurveLoop> curveLoops = extrusionLists[ii][0].GetLoops();
                                    XYZ extrudedDirection = extrusionLists[ii][0].ExtrusionDirection;

                                    int numLoops = curveLoops.Count;
                                    for (int jj = numLoops - 1; jj > 0; jj--)
                                    {
                                        ExtrusionExporter.AddOpeningData(exportBodyParams, extrusionLists[ii][0], curveLoops[jj]);
                                        extrusionLists[ii][0].RemoveLoopAt(jj);
                                    }
                                }

                                bool exportedAsExtrusion = false;
                                IFCExtrusionBasis whichBasis = extrusionLists[ii][0].ExtrusionBasis;
                                if (whichBasis >= 0)
                                {
                                    IFCAnyHandle extrusionHandle = ExtrusionExporter.CreateExtrudedSolidFromExtrusionData(exporterIFC, element, extrusionLists[ii][0]);
                                    if (!IFCAnyHandleUtil.IsNullOrHasNoValue(extrusionHandle))
                                    {
                                        bodyItems.Add(extrusionHandle);
                                        materialIdsForExtrusions.Add(exporterIFC.GetMaterialIdForCurrentExportState());

                                        IList<CurveLoop> curveLoops = extrusionLists[ii][0].GetLoops();
                                        XYZ extrusionDirection = extrusionLists[ii][0].ExtrusionDirection;

                                        if (exportBodyParams != null)
                                        {
                                            exportBodyParams.Slope = GeometryUtil.GetSimpleExtrusionSlope(extrusionDirection, whichBasis);
                                            exportBodyParams.ScaledLength = extrusionLists[ii][0].ScaledExtrusionLength;
                                            exportBodyParams.ExtrusionDirection = extrusionDirection;
                                            for (int kk = 1; kk < extrusionLists[ii].Count; kk++)
                                            {
                                                ExtrusionExporter.AddOpeningData(exportBodyParams, extrusionLists[ii][kk]);
                                            }

                                            Plane plane = null;
                                            double height = 0.0, width = 0.0;
                                            if (ExtrusionExporter.ComputeHeightWidthOfCurveLoop(curveLoops[0], plane, out height, out width))
                                            {
                                                exportBodyParams.ScaledHeight = UnitUtil.ScaleLength(height);
                                                exportBodyParams.ScaledWidth = UnitUtil.ScaleLength(width);
                                            }

                                            double area = ExporterIFCUtils.ComputeAreaOfCurveLoops(curveLoops);
                                            if (area > 0.0)
                                            {
                                                exportBodyParams.ScaledArea = UnitUtil.ScaleArea(area);
                                            }

                                            double innerPerimeter = ExtrusionExporter.ComputeInnerPerimeterOfCurveLoops(curveLoops);
                                            double outerPerimeter = ExtrusionExporter.ComputeOuterPerimeterOfCurveLoops(curveLoops);
                                            if (innerPerimeter > 0.0)
                                                exportBodyParams.ScaledInnerPerimeter = UnitUtil.ScaleLength(innerPerimeter);
                                            if (outerPerimeter > 0.0)
                                                exportBodyParams.ScaledOuterPerimeter = UnitUtil.ScaleLength(outerPerimeter);
                                        }
                                        exportedAsExtrusion = true;
                                        hasExtrusions = true;
                                    }
                                }

                                if (!exportedAsExtrusion)
                                {
                                    if (tryToExportAsSweptSolid)
                                        exportAsSweptSolid.Add(ii);
                                    else if (!canExportSolidModelRep)
                                    {
                                        tryToExportAsExtrusion = false;
                                        break;
                                    }
                                    else
                                        exportAsBRep.Add(new KeyValuePair<int, SimpleSweptSolidAnalyzer>(ii, null));
                                }
                            }
                        }
                    }

                    if (tryToExportAsSweptSolid)
                    {
                        int numCreatedSweptSolids = exportAsSweptSolid.Count;
                        for (int ii = 0; (ii < numCreatedSweptSolids) && tryToExportAsSweptSolid; ii++)
                        {
                            bool exported = false;
                            int geomIndex = exportAsSweptSolid[ii];
                            Solid solid = geometryList[geomIndex] as Solid;
                            SimpleSweptSolidAnalyzer simpleSweptSolidAnalyzer = null;
                            // TODO: allFaces to SweptSolid
                            if (solid != null)
                            {
                                // TODO: give normal hint below if we have an idea.
                                simpleSweptSolidAnalyzer = SweptSolidExporter.CanExportAsSweptSolid(exporterIFC, solid, null);

                                // If we are exporting as a BRep, we will keep the analyzer for later, if it isn't null.
                                if (simpleSweptSolidAnalyzer != null)
                                {
                                    if (!tryToExportAsSweptSolidAsTessellation)
                                    {
                                        SweptSolidExporter sweptSolidExporter = SweptSolidExporter.Create(exporterIFC, element, simpleSweptSolidAnalyzer, solid);
                                        IFCAnyHandle sweptHandle = (sweptSolidExporter != null) ? sweptSolidExporter.RepresentationItem : null;

                                        if (!IFCAnyHandleUtil.IsNullOrHasNoValue(sweptHandle))
                                        {
                                            bodyItems.Add(sweptHandle);
                                            materialIdsForExtrusions.Add(exporterIFC.GetMaterialIdForCurrentExportState());
                                            exported = true;
                                            hasRepresentationType = sweptSolidExporter.RepresentationType;

                                            // These are the only two valid cases for true sweep export: either an extrusion or a sweep.
                                            // We don't expect regular BReps or triangulated face sets here.
                                            if (sweptSolidExporter.isSpecificRepresentationType(ShapeRepresentationType.SweptSolid))
                                                hasExtrusions = true;
                                            else if (sweptSolidExporter.isSpecificRepresentationType(ShapeRepresentationType.AdvancedSweptSolid))
                                                hasSweptSolids = true;
                                        }
                                        else
                                            simpleSweptSolidAnalyzer = null;    // Didn't work for some reason.
                                    }
                                }
                            }

                            if (!exported)
                            {
                                exportAsBRep.Add(new KeyValuePair<int, SimpleSweptSolidAnalyzer>(geomIndex, simpleSweptSolidAnalyzer));
                                hasSweptSolidsAsBReps |= (simpleSweptSolidAnalyzer != null);
                            }
                        }
                    }

                    bool exportSucceeded = (exportAsBRep.Count == 0) && (tryToExportAsExtrusion || tryToExportAsSweptSolid)
                                && (hasExtrusions || hasSweptSolids || hasRepresentationType != ShapeRepresentationType.Undefined);
                    if (exportSucceeded || canExportSolidModelRep)
                    {
                        int sz = bodyItems.Count();
                        for (int ii = 0; ii < sz; ii++)
                            BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, document, bodyItems[ii], materialIdsForExtrusions[ii]);

                        if (exportSucceeded)
                        {
                            if (bodyData.RepresentationHnd == null)
                            {
                                HashSet<IFCAnyHandle> bodyItemSet = new HashSet<IFCAnyHandle>();
                                bodyItemSet.UnionWith(bodyItems);
                                if (hasExtrusions && !hasSweptSolids)
                                {
                                    bodyData.RepresentationHnd =
                                        RepresentationUtil.CreateSweptSolidRep(exporterIFC, element, categoryId, contextOfItems, bodyItemSet, bodyData.RepresentationHnd);
                                    bodyData.ShapeRepresentationType = ShapeRepresentationType.SweptSolid;
                                }
                                else if (hasSweptSolids && !hasExtrusions)
                                {
                                    bodyData.RepresentationHnd =
                                        RepresentationUtil.CreateAdvancedSweptSolidRep(exporterIFC, element, categoryId, contextOfItems, bodyItemSet, bodyData.RepresentationHnd);
                                    bodyData.ShapeRepresentationType = ShapeRepresentationType.AdvancedSweptSolid;
                                }
                                else if (hasRepresentationType == ShapeRepresentationType.Tessellation)
                                {
                                    bodyData.RepresentationHnd =
                                        RepresentationUtil.CreateTessellatedRep(exporterIFC, element, categoryId, contextOfItems, bodyItemSet, bodyData.RepresentationHnd);
                                    bodyData.ShapeRepresentationType = ShapeRepresentationType.Tessellation;
                                }
                                else
                                {
                                    bodyData.RepresentationHnd =
                                        RepresentationUtil.CreateSolidModelRep(exporterIFC, element, categoryId, contextOfItems, bodyItemSet);
                                    bodyData.ShapeRepresentationType = ShapeRepresentationType.SolidModel;
                                }
                            }

                            // TODO: include BRep, CSG, Clipping

                            XYZ lpOrig = ((bodyData != null) && (bodyData.OffsetTransform != null)) ? bodyData.OffsetTransform.Origin : new XYZ();
                            transformSetter.CreateLocalPlacementFromOffset(exporterIFC, bbox, exportBodyParams, lpOrig, unscaledTrfOrig);
                            tr.Commit();
                            return bodyData;
                        }
                    }

                    // If we are going to export a solid model, keep the created items.
                    if (!canExportSolidModelRep)
                        tr.RollBack();
                    else
                        tr.Commit();
                }

                // We couldn't export it as an extrusion; export as a solid, brep, or a surface model.
                if (!canExportSolidModelRep)
                {
                    exportAsExtrusion.Clear();
                    bodyItems.Clear();
                    if (exportBodyParams != null)
                        exportBodyParams.ClearOpenings();
                }

                if (exportAsExtrusion.Count == 0)
                {
                    // We used to clear exportAsBRep, but we need the SimpleSweptSolidAnalyzer information, so we will fill out the rest.
                    int numGeoms = geometryList.Count;
                    IList<KeyValuePair<int, SimpleSweptSolidAnalyzer>> newExportAsBRep = new List<KeyValuePair<int, SimpleSweptSolidAnalyzer>>(numGeoms);
                    int exportAsBRepCount = exportAsBRep.Count;
                    int currIndex = 0;
                    for (int ii = 0; ii < numGeoms; ii++)
                    {
                        if ((currIndex < exportAsBRepCount) && (ii == exportAsBRep[currIndex].Key))
                        {
                            newExportAsBRep.Add(exportAsBRep[currIndex]);
                            currIndex++;
                        }
                        else
                            newExportAsBRep.Add(new KeyValuePair<int, SimpleSweptSolidAnalyzer>(ii, null));
                    }
                    exportAsBRep = newExportAsBRep;
                }
            }

            // If we created some extrusions that we are using (e.g., creating a solid model), and we didn't use an offset transform for the extrusions, don't do it here either.
            bool supportOffsetTransformForBreps = !hasSweptSolidsAsBReps;
            bool disallowOffsetTransformForBreps = (exportAsExtrusion.Count > 0) && !useOffsetTransformForExtrusions;
            bool useOffsetTransformForBReps = options.AllowOffsetTransform && supportOffsetTransformForBreps && !disallowOffsetTransformForBreps;

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                using (TransformSetter transformSetter = TransformSetter.Create())
                {
                    // Need to do extra work to support offset transforms if we are using the sweep analyzer.
                    if (useOffsetTransformForBReps)
                        bodyData.OffsetTransform = transformSetter.InitializeFromBoundingBox(exporterIFC, bbox, exportBodyParams, out unscaledTrfOrig);

                    BodyData brepBodyData =
                        ExportBodyAsBRep(exporterIFC, geometryList, exportAsBRep, bodyItems, element, categoryId, overrideMaterialId, contextOfItems, eps, options, bodyData);
                    if (brepBodyData == null)
                        tr.RollBack();
                    else
                    {
                        XYZ lpOrig = ((bodyData != null) && (bodyData.OffsetTransform != null)) ? bodyData.OffsetTransform.Origin : new XYZ();
                        transformSetter.CreateLocalPlacementFromOffset(exporterIFC, bbox, exportBodyParams, lpOrig, unscaledTrfOrig);
                        tr.Commit();
                    }
                    return brepBodyData;
                }
            }
        }
        /// <summary>
        /// Creates a SweptSolidExporter.
        /// </summary>
        /// <param name="exporterIFC">The exporter.</param>
        /// <param name="element">The element.</param>
        /// <param name="solid">The solid.</param>
        /// <param name="normal">The normal of the plane that the path lies on.</param>
        /// <returns>The SweptSolidExporter.</returns>
        public static SweptSolidExporter Create(ExporterIFC exporterIFC, Element element, SimpleSweptSolidAnalyzer sweptAnalyzer, GeometryObject geomObject)
        {
            try
            {
                if (sweptAnalyzer == null)
                    return null;

                SweptSolidExporter sweptSolidExporter = null;

                IList<Revit.IFC.Export.Utility.GeometryUtil.FaceBoundaryType> faceBoundaryTypes;
                IList<CurveLoop> faceBoundaries = GeometryUtil.GetFaceBoundaries(sweptAnalyzer.ProfileFace, null, out faceBoundaryTypes);

                string profileName = null;
                if (element != null)
                {
                    ElementType type = element.Document.GetElement(element.GetTypeId()) as ElementType;
                    if (type != null)
                        profileName = type.Name;
                }

                // Is it really an extrusion?
                if (sweptAnalyzer.PathCurve is Line)
                {
                    Line line = sweptAnalyzer.PathCurve as Line;

                    // invalid case
                    if (MathUtil.VectorsAreOrthogonal(line.Direction, sweptAnalyzer.ProfileFace.FaceNormal))
                        return null;

                    sweptSolidExporter = new SweptSolidExporter();
                    sweptSolidExporter.RepresentationType = ShapeRepresentationType.SweptSolid;
                    Plane plane = new Plane(sweptAnalyzer.ProfileFace.FaceNormal, sweptAnalyzer.ProfileFace.Origin);
                    sweptSolidExporter.RepresentationItem = ExtrusionExporter.CreateExtrudedSolidFromCurveLoop(exporterIFC, profileName, faceBoundaries, plane,
                        line.Direction, UnitUtil.ScaleLength(line.Length));
                }
                else
                {
                    sweptSolidExporter = new SweptSolidExporter();
                    if (ExporterCacheManager.ExportOptionsCache.ExportAs4)
                    {
                        // Use tessellated geometry in IFC Reference View
                        if (ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView)
                        {
                            // TODO: Create CreateSimpleSweptSolidAsTessellation routine that takes advantage of the superior tessellation of this class.
                            BodyExporterOptions options = new BodyExporterOptions(false);
                            sweptSolidExporter.RepresentationItem = BodyExporter.ExportBodyAsTriangulatedFaceSet(exporterIFC, element, options, geomObject);
                            sweptSolidExporter.RepresentationType = ShapeRepresentationType.Tessellation;
                        }
                        else
                        {
                            sweptSolidExporter.RepresentationItem = CreateSimpleSweptSolid(exporterIFC, profileName, faceBoundaries, sweptAnalyzer.ReferencePlaneNormal, sweptAnalyzer.PathCurve);
                            sweptSolidExporter.RepresentationType = ShapeRepresentationType.AdvancedSweptSolid;
                        }
                    }
                    else
                    {
                        sweptSolidExporter.Facets = CreateSimpleSweptSolidAsBRep(exporterIFC, profileName, faceBoundaries, sweptAnalyzer.ReferencePlaneNormal, sweptAnalyzer.PathCurve);
                        sweptSolidExporter.RepresentationType = ShapeRepresentationType.Brep;
                    }
                }
                return sweptSolidExporter;
            }
            catch (Exception)
            {
                return null;
            }
        }
Пример #32
0
        /// <summary>
        /// Exports list of solids and meshes to IFC body representation.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="categoryId">The category id.</param>
        /// <param name="solids">The solids.</param>
        /// <param name="meshes">The meshes.</param>
        /// <param name="options">The settings for how to export the body.</param>
        /// <param name="useMappedGeometriesIfPossible">If extrusions are not possible, and there is redundant geometry, 
        /// use a MappedRepresentation.</param>
        /// <param name="useGroupsIfPossible">If extrusions are not possible, and the element is part of a group, 
        /// use the cached version if it exists, or create it.</param>
        /// <param name="exportBodyParams">The extrusion creation data.</param>
        /// <returns>The body data.</returns>
        public static BodyData ExportBody(ExporterIFC exporterIFC,
            Element element,
            ElementId categoryId,
            ElementId overrideMaterialId,
            IList<Solid> solids,
            IList<Mesh> meshes,
            BodyExporterOptions options,
            IFCExtrusionCreationData exportBodyParams)
        {
            IList<GeometryObject> objects = new List<GeometryObject>();
            foreach (Solid solid in solids)
                objects.Add(solid);
            foreach (Mesh mesh in meshes)
                objects.Add(mesh);

            return ExportBody(exporterIFC, element, categoryId, overrideMaterialId, objects, options, exportBodyParams);
        }
Пример #33
0
        /// <summary>
        /// Exports an element to IFC footing.
        /// </summary>
        /// <param name="exporterIFC">
        /// The ExporterIFC object.
        /// </param>
        /// <param name="element">
        /// The element.
        /// </param>
        /// <param name="geometryElement">
        /// The geometry element.
        /// </param>
        /// <param name="ifcEnumType">
        /// The string value represents the IFC type.
        /// </param>
        /// <param name="productWrapper">
        /// The ProductWrapper.
        /// </param>
        public static void ExportFooting(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement,
                                         string ifcEnumType, ProductWrapper productWrapper)
        {
            // export parts or not
            bool exportParts = PartExporter.CanExportParts(element);

            if (exportParts && !PartExporter.CanExportElementInPartExport(element, element.LevelId, false))
            {
                return;
            }

            // Check the intended IFC entity or type name is in the exclude list specified in the UI
            Common.Enums.IFCEntityType elementClassTypeEnum;
            if (Enum.TryParse <Common.Enums.IFCEntityType>("IfcFooting", out elementClassTypeEnum))
            {
                if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum))
                {
                    return;
                }
            }

            IFCFile file = exporterIFC.GetFile();

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element))
                {
                    using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                    {
                        ecData.SetLocalPlacement(setter.LocalPlacement);

                        IFCAnyHandle prodRep = null;
                        ElementId    matId   = ElementId.InvalidElementId;
                        if (!exportParts)
                        {
                            ElementId catId = CategoryUtil.GetSafeCategoryId(element);


                            matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geometryElement, exporterIFC, element);
                            BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow);
                            prodRep = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC,
                                                                                                 element, catId, geometryElement, bodyExporterOptions, null, ecData, true);
                            if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodRep))
                            {
                                ecData.ClearOpenings();
                                return;
                            }
                        }

                        string instanceGUID        = GUIDUtil.CreateGUID(element);
                        string instanceName        = NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element));
                        string instanceDescription = NamingUtil.GetDescriptionOverride(element, null);
                        string instanceObjectType  = NamingUtil.GetObjectTypeOverride(element, exporterIFC.GetFamilyName());
                        string instanceTag         = NamingUtil.GetTagOverride(element, NamingUtil.CreateIFCElementId(element));
                        string footingType         = GetIFCFootingType(ifcEnumType); // need to keep it for legacy support when original data follows slightly diff naming
                        footingType = IFCValidateEntry.GetValidIFCType(element, footingType);

                        IFCAnyHandle footing = IFCInstanceExporter.CreateFooting(file, instanceGUID, ExporterCacheManager.OwnerHistoryHandle,
                                                                                 instanceName, instanceDescription, instanceObjectType, ecData.GetLocalPlacement(), prodRep, instanceTag, footingType);

                        if (exportParts)
                        {
                            PartExporter.ExportHostPart(exporterIFC, element, footing, productWrapper, setter, setter.LocalPlacement, null);
                        }
                        else
                        {
                            if (matId != ElementId.InvalidElementId)
                            {
                                CategoryUtil.CreateMaterialAssociation(exporterIFC, footing, matId);
                            }
                        }

                        productWrapper.AddElement(element, footing, setter, ecData, true);

                        OpeningUtil.CreateOpeningsIfNecessary(footing, element, ecData, null,
                                                              exporterIFC, ecData.GetLocalPlacement(), setter, productWrapper);
                    }
                }

                tr.Commit();
            }
        }
Пример #34
0
 /// <summary>
 /// Exports a geometry object to IFC body representation.
 /// </summary>
 /// <param name="exporterIFC">The ExporterIFC object.</param>
 /// <param name="categoryId">The category id.</param>
 /// <param name="geometryObject">The geometry object.</param>
 /// <param name="options">The settings for how to export the body.</param>
 /// <param name="exportBodyParams">The extrusion creation data.</param>
 /// <returns>The body data.</returns>
 public static BodyData ExportBody(ExporterIFC exporterIFC,
    Element element, ElementId categoryId, ElementId overrideMaterialId,
    GeometryObject geometryObject, BodyExporterOptions options,
    IFCExtrusionCreationData exportBodyParams)
 {
     IList<GeometryObject> geomList = new List<GeometryObject>();
     if (geometryObject is Solid)
     {
         IList<Solid> splitVolumes = GeometryUtil.SplitVolumes(geometryObject as Solid);
         foreach (Solid solid in splitVolumes)
             geomList.Add(solid);
     }
     else
         geomList.Add(geometryObject);
     return ExportBody(exporterIFC, element, categoryId, overrideMaterialId, geomList, options, exportBodyParams);
 }
Пример #35
0
        /// <summary>
        /// Exports a beam to IFC beam if it has an axis representation and only one Solid as its geometry, ideally as an extrusion, potentially with clippings and openings.
        /// </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>
        /// <param name="dontExport">An output value that says that the element shouldn't be exported at all.</param>
        /// <returns>The created handle.</returns>
        /// <remarks>In the original implementation, the ExportBeam function would export each beam as its own individual geometry (that is, not use representation maps).
        /// For non-standard beams, this could result in massive IFC files.  Now, we use the ExportBeamAsStandardElement function and limit its scope, and instead
        /// resort to the standard FamilyInstanceExporter.ExportFamilyInstanceAsMappedItem for more complicated objects categorized as beams.  This has the following pros and cons:
        /// Pro: possiblity for massively reduced file sizes for files containing repeated complex beam families
        /// Con: some beams that may have had an "Axis" representation before will no longer have them, although this possibility is minimized.
        /// Con: some beams that have 1 Solid and an axis, but that Solid will be heavily faceted, won't be helped by this improvement.
        /// It is intended that we phase out this routine entirely and instead teach ExportFamilyInstanceAsMappedItem how to sometimes export the Axis representation for beams.</remarks>
        public static IFCAnyHandle ExportBeamAsStandardElement(ExporterIFC exporterIFC,
                                                               Element element, GeometryElement geometryElement, ProductWrapper productWrapper, out bool dontExport)
        {
            dontExport = true;
            IList <GeometryObject> geomObjects = BeamGeometryToExport(exporterIFC, element, geometryElement, out dontExport);

            if (dontExport)
            {
                return(null);
            }

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

            using (IFCTransaction transaction = new IFCTransaction(file))
            {
                BeamAxisInfo axisInfo      = GetBeamAxisTransform(element);
                bool         canExportAxis = (axisInfo != null);

                Curve     curve         = canExportAxis ? axisInfo.Axis : null;
                XYZ       beamDirection = canExportAxis ? axisInfo.AxisDirection : null;
                Transform orientTrf     = canExportAxis ? axisInfo.LCSAsTransform : null;

                using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element, null, orientTrf))
                {
                    IFCAnyHandle localPlacement = setter.LocalPlacement;
                    using (IFCExtrusionCreationData extrusionCreationData = new IFCExtrusionCreationData())
                    {
                        extrusionCreationData.SetLocalPlacement(localPlacement);
                        if (canExportAxis && (orientTrf.BasisX != null))
                        {
                            extrusionCreationData.CustomAxis            = beamDirection;
                            extrusionCreationData.PossibleExtrusionAxes = IFCExtrusionAxes.TryCustom;
                        }
                        else
                        {
                            extrusionCreationData.PossibleExtrusionAxes = IFCExtrusionAxes.TryXY;
                        }

                        ElementId catId = CategoryUtil.GetSafeCategoryId(element);

                        // There may be an offset to make the local coordinate system
                        // be near the origin.  This offset will be used to move the axis to the new LCS.
                        Transform offsetTransform = null;

                        // The list of materials in the solids or meshes.
                        ICollection <ElementId> materialIds = null;

                        // The representation handle generated from one of the methods below.
                        BeamBodyAsExtrusionInfo extrusionInfo = CreateBeamGeometryAsExtrusion(exporterIFC, element, catId, geomObjects, axisInfo);
                        if (extrusionInfo != null && extrusionInfo.DontExport)
                        {
                            dontExport = true;
                            return(null);
                        }

                        IFCAnyHandle repHnd = (extrusionInfo != null) ? extrusionInfo.RepresentationHandle : null;

                        if (!IFCAnyHandleUtil.IsNullOrHasNoValue(repHnd))
                        {
                            materialIds = extrusionInfo.Materials;
                            extrusionCreationData.Slope = extrusionInfo.Slope;
                        }
                        else
                        {
                            // Here is where we limit the scope of how complex a case we will still try to export as a standard element.
                            // This is explicitly added so that many curved beams that can be represented by a reasonable facetation because of the
                            // SweptSolidExporter can still have an Axis representation.
                            BodyData bodyData = null;

                            BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow);
                            if (geomObjects != null && geomObjects.Count == 1 && geomObjects[0] is Solid)
                            {
                                bodyData = BodyExporter.ExportBody(exporterIFC, element, catId, ElementId.InvalidElementId,
                                                                   geomObjects[0], bodyExporterOptions, extrusionCreationData);

                                repHnd          = bodyData.RepresentationHnd;
                                materialIds     = bodyData.MaterialIds;
                                offsetTransform = bodyData.OffsetTransform;
                            }
                        }

                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(repHnd))
                        {
                            extrusionCreationData.ClearOpenings();
                            return(null);
                        }

                        IList <IFCAnyHandle> representations = new List <IFCAnyHandle>();

                        IFCAnyHandle axisRep = CreateBeamAxis(exporterIFC, element, catId, axisInfo, offsetTransform);
                        if (!IFCAnyHandleUtil.IsNullOrHasNoValue(axisRep))
                        {
                            representations.Add(axisRep);
                        }
                        representations.Add(repHnd);

                        Transform    boundingBoxTrf = (offsetTransform == null) ? Transform.Identity : offsetTransform.Inverse;
                        IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, geometryElement, boundingBoxTrf);
                        if (boundingBoxRep != null)
                        {
                            representations.Add(boundingBoxRep);
                        }

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

                        string instanceGUID        = GUIDUtil.CreateGUID(element);
                        string instanceName        = NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element));
                        string instanceDescription = NamingUtil.GetDescriptionOverride(element, null);
                        string instanceObjectType  = NamingUtil.GetObjectTypeOverride(element, NamingUtil.CreateIFCObjectName(exporterIFC, element));
                        string instanceTag         = NamingUtil.GetTagOverride(element, NamingUtil.CreateIFCElementId(element));
                        string preDefinedType      = "BEAM"; // Default predefined type for Beam
                        preDefinedType = IFCValidateEntry.GetValidIFCType(element, preDefinedType);

                        beam = IFCInstanceExporter.CreateBeam(file, instanceGUID, ExporterCacheManager.OwnerHistoryHandle,
                                                              instanceName, instanceDescription, instanceObjectType, extrusionCreationData.GetLocalPlacement(), prodRep, instanceTag, preDefinedType);

                        productWrapper.AddElement(element, beam, setter, extrusionCreationData, true);

                        OpeningUtil.CreateOpeningsIfNecessary(beam, element, extrusionCreationData, offsetTransform, exporterIFC,
                                                              extrusionCreationData.GetLocalPlacement(), setter, productWrapper);

                        FamilyTypeInfo typeInfo = new FamilyTypeInfo();
                        typeInfo.ScaledDepth          = extrusionCreationData.ScaledLength;
                        typeInfo.ScaledArea           = extrusionCreationData.ScaledArea;
                        typeInfo.ScaledInnerPerimeter = extrusionCreationData.ScaledInnerPerimeter;
                        typeInfo.ScaledOuterPerimeter = extrusionCreationData.ScaledOuterPerimeter;
                        PropertyUtil.CreateBeamColumnBaseQuantities(exporterIFC, beam, element, typeInfo, null);

                        if (materialIds.Count != 0)
                        {
                            CategoryUtil.CreateMaterialAssociations(exporterIFC, beam, materialIds);
                        }

                        // Register the beam's IFC handle for later use by truss and beam system export.
                        ExporterCacheManager.ElementToHandleCache.Register(element.Id, beam);
                    }
                }

                transaction.Commit();
                return(beam);
            }
        }
Пример #36
0
        /// <summary>
        /// Exports a geometry object to IFC body representation.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="categoryId">The category id.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="options">The settings for how to export the body.</param>
        /// <param name="exportBodyParams">The extrusion creation data.</param>
        /// <param name="offsetTransform">The transform used to shift the body to the local origin.</param>
        /// <returns>The body data.</returns>
        public static BodyData ExportBody(ExporterIFC exporterIFC,
           Element element, ElementId categoryId, ElementId overrideMaterialId,
           GeometryElement geometryElement, BodyExporterOptions options,
           IFCExtrusionCreationData exportBodyParams)
        {
            SolidMeshGeometryInfo info = null;
            IList<GeometryObject> geomList = new List<GeometryObject>();

            if (!ExporterCacheManager.ExportOptionsCache.ExportAs2x2)
            {
                info = GeometryUtil.GetSplitSolidMeshGeometry(geometryElement);
                IList<Mesh> meshes = info.GetMeshes();
                if (meshes.Count == 0)
                {
                    IList<Solid> solidList = info.GetSolids();
                    foreach (Solid solid in solidList)
                    {
                        geomList.Add(solid);
                    }
                }
            }

            if (geomList.Count == 0)
                geomList.Add(geometryElement);

            return ExportBody(exporterIFC, element, categoryId, overrideMaterialId, geomList,
                options, exportBodyParams);
        }
Пример #37
0
        /// <summary>
        /// Exports a CeilingAndFloor element to IFC.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="floor">The floor element.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        public static void ExportCeilingAndFloorElement(ExporterIFC exporterIFC, CeilingAndFloor floorElement, GeometryElement geometryElement,
                                                        ProductWrapper productWrapper)
        {
            if (geometryElement == null)
            {
                return;
            }

            // export parts or not
            bool exportParts = PartExporter.CanExportParts(floorElement);

            if (exportParts && !PartExporter.CanExportElementInPartExport(floorElement, floorElement.LevelId, false))
            {
                return;
            }

            IFCFile file = exporterIFC.GetFile();

            string            ifcEnumType;
            IFCExportInfoPair exportType = ExporterUtil.GetExportType(exporterIFC, floorElement, out ifcEnumType);
            IFCAnyHandle      type       = null;

            // Check the intended IFC entity or type name is in the exclude list specified in the UI
            Common.Enums.IFCEntityType elementClassTypeEnum;
            if (Enum.TryParse <Common.Enums.IFCEntityType>(exportType.ToString(), out elementClassTypeEnum))
            {
                if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum))
                {
                    return;
                }
            }

            string predefinedType = null;

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                bool canExportAsContainerOrWithExtrusionAnalyzer = (!exportParts && (floorElement is Floor));

                if (canExportAsContainerOrWithExtrusionAnalyzer)
                {
                    // Try to export the Floor slab as a container.  If that succeeds, we are done.
                    // If we do export the floor as a container, it will take care of the local placement and transform there, so we need to leave
                    // this out of the IFCTransformSetter and PlacementSetter scopes below, or else we'll get double transforms.
                    IFCAnyHandle floorHnd = RoofExporter.ExportRoofOrFloorAsContainer(exporterIFC, ifcEnumType, floorElement, geometryElement, productWrapper);
                    if (!IFCAnyHandleUtil.IsNullOrHasNoValue(floorHnd))
                    {
                        tr.Commit();
                        return;
                    }
                }

                IList <IFCAnyHandle> slabHnds        = new List <IFCAnyHandle>();
                IList <IFCAnyHandle> brepSlabHnds    = new List <IFCAnyHandle>();
                IList <IFCAnyHandle> nonBrepSlabHnds = new List <IFCAnyHandle>();

                IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle;

                using (IFCTransformSetter transformSetter = IFCTransformSetter.Create())
                {
                    using (PlacementSetter placementSetter = PlacementSetter.Create(exporterIFC, floorElement))
                    {
                        IFCAnyHandle localPlacement = placementSetter.LocalPlacement;

                        // The routine ExportExtrudedSlabOpenings is called if exportedAsInternalExtrusion is true, and it requires having a valid level association.
                        // Disable calling ExportSlabAsExtrusion if we can't handle potential openings.
                        bool canExportAsInternalExtrusion = placementSetter.LevelInfo != null;
                        bool exportedAsInternalExtrusion  = false;

                        ElementId catId = CategoryUtil.GetSafeCategoryId(floorElement);

                        IList <IFCAnyHandle>             prodReps        = new List <IFCAnyHandle>();
                        IList <ShapeRepresentationType>  repTypes        = new List <ShapeRepresentationType>();
                        IList <IList <CurveLoop> >       extrusionLoops  = new List <IList <CurveLoop> >();
                        IList <IFCExtrusionCreationData> loopExtraParams = new List <IFCExtrusionCreationData>();
                        Plane floorPlane = GeometryUtil.CreateDefaultPlane();

                        IList <IFCAnyHandle> localPlacements = new List <IFCAnyHandle>();

                        if (canExportAsContainerOrWithExtrusionAnalyzer)
                        {
                            Floor floor = floorElement as Floor;

                            // Next, try to use the ExtrusionAnalyzer for the limited cases it handles - 1 solid, no openings, end clippings only.
                            // Also limited to cases with line and arc boundaries.
                            //
                            SolidMeshGeometryInfo solidMeshInfo = GeometryUtil.GetSplitSolidMeshGeometry(geometryElement);
                            IList <Solid>         solids        = solidMeshInfo.GetSolids();
                            IList <Mesh>          meshes        = solidMeshInfo.GetMeshes();

                            if (solids.Count == 1 && meshes.Count == 0)
                            {
                                bool completelyClipped;
                                // floorExtrusionDirection is set to (0, 0, -1) because extrusionAnalyzerFloorPlane is computed from the top face of the floor
                                XYZ floorExtrusionDirection = new XYZ(0, 0, -1);
                                XYZ modelOrigin             = XYZ.Zero;

                                XYZ floorOrigin = floor.GetVerticalProjectionPoint(modelOrigin, FloorFace.Top);
                                if (floorOrigin == null)
                                {
                                    // GetVerticalProjectionPoint may return null if FloorFace.Top is an edited face that doesn't
                                    // go through the Revit model origin.  We'll try the midpoint of the bounding box instead.
                                    BoundingBoxXYZ boundingBox = floorElement.get_BoundingBox(null);
                                    modelOrigin = (boundingBox.Min + boundingBox.Max) / 2.0;
                                    floorOrigin = floor.GetVerticalProjectionPoint(modelOrigin, FloorFace.Top);
                                }

                                if (floorOrigin != null)
                                {
                                    XYZ   floorDir = floor.GetNormalAtVerticalProjectionPoint(floorOrigin, FloorFace.Top);
                                    Plane extrusionAnalyzerFloorBasePlane = GeometryUtil.CreatePlaneByNormalAtOrigin(floorDir);

                                    GenerateAdditionalInfo additionalInfo     = ExporterCacheManager.ExportOptionsCache.ExportAs4 ? GenerateAdditionalInfo.GenerateFootprint : GenerateAdditionalInfo.None;
                                    HandleAndData          floorAndProperties =
                                        ExtrusionExporter.CreateExtrusionWithClippingAndProperties(exporterIFC, floorElement,
                                                                                                   catId, solids[0], extrusionAnalyzerFloorBasePlane, floorOrigin, floorExtrusionDirection, null, out completelyClipped,
                                                                                                   addInfo: additionalInfo);
                                    if (completelyClipped)
                                    {
                                        return;
                                    }
                                    if (floorAndProperties.Handle != null)
                                    {
                                        IList <IFCAnyHandle> representations = new List <IFCAnyHandle>();
                                        representations.Add(floorAndProperties.Handle);

                                        // Footprint representation will only be exported in export to IFC4
                                        if (((additionalInfo & GenerateAdditionalInfo.GenerateFootprint) != 0) && (floorAndProperties.FootprintInfo != null))
                                        {
                                            if (!(IFCAnyHandleUtil.IsNullOrHasNoValue(floorAndProperties.FootprintInfo.FootPrintHandle)))
                                            {
                                                representations.Add(floorAndProperties.FootprintInfo.FootPrintHandle);
                                            }
                                        }

                                        IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, representations);
                                        prodReps.Add(prodRep);
                                        repTypes.Add(ShapeRepresentationType.SweptSolid);

                                        if (floorAndProperties.Data != null)
                                        {
                                            loopExtraParams.Add(floorAndProperties.Data);
                                        }
                                    }
                                }
                            }
                        }

                        // Use internal routine as backup that handles openings.
                        if (prodReps.Count == 0 && canExportAsInternalExtrusion && !ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView)
                        {
                            //IList<IFCAnyHandle> prodRepsTmp = new List<IFCAnyHandle>();
                            exportedAsInternalExtrusion = ExporterIFCUtils.ExportSlabAsExtrusion(exporterIFC, floorElement,
                                                                                                 geometryElement, transformSetter, localPlacement, out localPlacements, out prodReps,
                                                                                                 out extrusionLoops, out loopExtraParams, floorPlane);
                            for (int ii = 0; ii < prodReps.Count; ii++)
                            {
                                // all are extrusions
                                repTypes.Add(ShapeRepresentationType.SweptSolid);

                                // Footprint representation will only be exported in export to IFC4
                                if (ExporterCacheManager.ExportOptionsCache.ExportAs4)
                                {
                                    if (extrusionLoops.Count > ii)
                                    {
                                        if (extrusionLoops[ii].Count > 0)
                                        {
                                            // Get the extrusion footprint using the first Curveloop. Transform needs to be obtained from the returned local placement
                                            Transform    lcs = ExporterIFCUtils.GetUnscaledTransform(exporterIFC, localPlacements[ii]);
                                            IFCAnyHandle footprintGeomRepItem = GeometryUtil.CreateIFCCurveFromCurveLoop(exporterIFC, extrusionLoops[ii][0], lcs, floorPlane.Normal);

                                            IFCAnyHandle        contextOfItemsFootprint = exporterIFC.Get3DContextHandle("FootPrint");
                                            ISet <IFCAnyHandle> repItem = new HashSet <IFCAnyHandle>();
                                            repItem.Add(footprintGeomRepItem);
                                            IFCAnyHandle footprintShapeRepresentation = RepresentationUtil.CreateBaseShapeRepresentation(exporterIFC, contextOfItemsFootprint, "FootPrint", "Curve2D", repItem);
                                            //representations.Add(footprintShapeRepresentation);
                                            IList <IFCAnyHandle> reps = new List <IFCAnyHandle>();
                                            reps.Add(footprintShapeRepresentation);
                                            IFCAnyHandleUtil.AddRepresentations(prodReps[ii], reps);
                                        }
                                    }
                                }
                            }
                        }

                        if (prodReps.Count == 0)
                        {
                            using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                            {
                                // Brep representation using tesellation after ExportSlabAsExtrusion does not return prodReps
                                BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.Medium);
                                BodyData            bodyData;
                                IFCAnyHandle        prodDefHnd = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC,
                                                                                                                            floorElement, catId, geometryElement, bodyExporterOptions, null, ecData, out bodyData);
                                if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodDefHnd))
                                {
                                    ecData.ClearOpenings();
                                    return;
                                }

                                prodReps.Add(prodDefHnd);
                                repTypes.Add(bodyData.ShapeRepresentationType);
                            }
                        }

                        // Create the slab from either the extrusion or the BRep information.
                        string ifcGUID = GUIDUtil.CreateGUID(floorElement);

                        int numReps = exportParts ? 1 : prodReps.Count;

                        switch (exportType.ExportInstance)
                        {
                        case IFCEntityType.IfcFooting:
                            if (ExporterCacheManager.ExportOptionsCache.ExportAs4)
                            {
                                predefinedType = IFCValidateEntry.GetValidIFCType <Revit.IFC.Export.Toolkit.IFC4.IFCFootingType>(floorElement, ifcEnumType, null);
                            }
                            else
                            {
                                predefinedType = IFCValidateEntry.GetValidIFCType <IFCFootingType>(floorElement, ifcEnumType, null);
                            }
                            break;

                        case IFCEntityType.IfcCovering:
                            predefinedType = IFCValidateEntry.GetValidIFCType <IFCCoveringType>(floorElement, ifcEnumType, "FLOORING");
                            break;

                        case IFCEntityType.IfcRamp:
                            if (ExporterCacheManager.ExportOptionsCache.ExportAs4)
                            {
                                predefinedType = IFCValidateEntry.GetValidIFCType <Revit.IFC.Export.Toolkit.IFC4.IFCRampType>(floorElement, ifcEnumType, null);
                            }
                            else
                            {
                                predefinedType = IFCValidateEntry.GetValidIFCType <IFCRampType>(floorElement, ifcEnumType, null);
                            }
                            break;

                        default:
                            bool            isBaseSlab      = false;
                            AnalyticalModel analyticalModel = floorElement.GetAnalyticalModel();
                            if (analyticalModel != null)
                            {
                                AnalyzeAs slabFoundationType = analyticalModel.GetAnalyzeAs();
                                isBaseSlab = (slabFoundationType == AnalyzeAs.SlabOnGrade) || (slabFoundationType == AnalyzeAs.Mat);
                            }
                            predefinedType = IFCValidateEntry.GetValidIFCType <IFCSlabType>(floorElement, ifcEnumType, isBaseSlab ? "BASESLAB" : "FLOOR");
                            break;
                        }

                        for (int ii = 0; ii < numReps; ii++)
                        {
                            string ifcName = NamingUtil.GetNameOverride(floorElement, NamingUtil.GetIFCNamePlusIndex(floorElement, ii == 0 ? -1 : ii + 1));

                            string       currentGUID       = (ii == 0) ? ifcGUID : GUIDUtil.CreateGUID();
                            IFCAnyHandle localPlacementHnd = exportedAsInternalExtrusion ? localPlacements[ii] : localPlacement;

                            IFCAnyHandle slabHnd = null;
                            slabHnd = IFCInstanceExporter.CreateGenericIFCEntity(exportType, exporterIFC, floorElement, currentGUID, ownerHistory,
                                                                                 localPlacementHnd, exportParts ? null : prodReps[ii]);
                            if (!string.IsNullOrEmpty(ifcName))
                            {
                                IFCAnyHandleUtil.SetAttribute(slabHnd, "Name", ifcName);
                            }
                            if (!string.IsNullOrEmpty(predefinedType))
                            {
                                IFCAnyHandleUtil.SetAttribute(slabHnd, "PredefinedType", predefinedType, true);
                            }

                            if (IFCAnyHandleUtil.IsNullOrHasNoValue(slabHnd))
                            {
                                return;
                            }
                            IFCAnyHandleUtil.SetAttribute(slabHnd, "Name", ifcName);
                            if (exportParts)
                            {
                                PartExporter.ExportHostPart(exporterIFC, floorElement, slabHnd, productWrapper, placementSetter, localPlacementHnd, null);
                            }

                            slabHnds.Add(slabHnd);

                            if (!exportParts)
                            {
                                if (repTypes[ii] == ShapeRepresentationType.Brep || repTypes[ii] == ShapeRepresentationType.Tessellation)
                                {
                                    brepSlabHnds.Add(slabHnd);
                                }
                                else
                                {
                                    nonBrepSlabHnds.Add(slabHnd);
                                }
                            }
                        }

                        for (int ii = 0; ii < numReps; ii++)
                        {
                            IFCExtrusionCreationData loopExtraParam = ii < loopExtraParams.Count ? loopExtraParams[ii] : null;
                            productWrapper.AddElement(floorElement, slabHnds[ii], placementSetter, loopExtraParam, true);

                            type = ExporterUtil.CreateGenericTypeFromElement(floorElement, exportType, file, ownerHistory, predefinedType, productWrapper);
                            ExporterCacheManager.TypeRelationsCache.Add(type, slabHnds[ii]);
                        }

                        // This call to the native function appears to create Brep opening also when appropriate. But the creation of the IFC instances is not
                        //   controllable from the managed code. Therefore in some cases BRep geometry for Opening will still be exported even in the Reference View
                        if (exportedAsInternalExtrusion)
                        {
                            ExporterIFCUtils.ExportExtrudedSlabOpenings(exporterIFC, floorElement, placementSetter.LevelInfo,
                                                                        localPlacements[0], slabHnds, extrusionLoops, floorPlane, productWrapper.ToNative());
                        }
                    }

                    if (!exportParts)
                    {
                        if (nonBrepSlabHnds.Count > 0)
                        {
                            HostObjectExporter.ExportHostObjectMaterials(exporterIFC, floorElement, nonBrepSlabHnds,
                                                                         geometryElement, productWrapper, ElementId.InvalidElementId, Toolkit.IFCLayerSetDirection.Axis3, false, type);
                        }
                        if (brepSlabHnds.Count > 0)
                        {
                            HostObjectExporter.ExportHostObjectMaterials(exporterIFC, floorElement, brepSlabHnds,
                                                                         geometryElement, productWrapper, ElementId.InvalidElementId, Toolkit.IFCLayerSetDirection.Axis3, true, type);
                        }
                    }
                }
                tr.Commit();

                return;
            }
        }
Пример #38
0
        /// <summary>
        /// Exports a roof to IfcRoof.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="roof">The roof element.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        /// <param name="exportRoofAsSingleGeometry">Export roof as single geometry.</param>
        public static void ExportRoof(ExporterIFC exporterIFC, Element roof, ref GeometryElement geometryElement,
                                      ProductWrapper productWrapper, bool exportRoofAsSingleGeometry = false)
        {
            if (roof == null || geometryElement == null)
            {
                return;
            }

            string            ifcEnumType;
            IFCExportInfoPair roofExportType = ExporterUtil.GetProductExportType(exporterIFC, roof, out ifcEnumType);

            if (roofExportType.IsUnKnown)
            {
                roofExportType = new IFCExportInfoPair(IFCEntityType.IfcRoof, "");
            }

            MaterialLayerSetInfo layersetInfo = new MaterialLayerSetInfo(exporterIFC, roof, productWrapper);
            IFCFile  file = exporterIFC.GetFile();
            Document doc  = roof.Document;

            using (SubTransaction tempPartTransaction = new SubTransaction(doc))
            {
                // For IFC4RV export, Roof will be split into its parts(temporarily) in order to export the roof by its parts
                ExporterUtil.CreateParts(roof, layersetInfo.MaterialIds.Count, ref geometryElement);
                bool exportByComponents = ExporterUtil.CanExportByComponentsOrParts(roof) == ExporterUtil.ExportPartAs.ShapeAspect;

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

                    using (PlacementSetter placementSetter = PlacementSetter.Create(exporterIFC, roof, null, null, overrideContainerId, overrideContainerHnd))
                    {
                        using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                        {
                            // If the roof is an in-place family, we will allow any arbitrary orientation.  While this may result in some
                            // in-place "cubes" exporting with the wrong direction, it is unlikely that an in-place family would be
                            // used for this reason in the first place.
                            ecData.PossibleExtrusionAxes   = (roof is FamilyInstance) ? IFCExtrusionAxes.TryXYZ : IFCExtrusionAxes.TryZ;
                            ecData.AreInnerRegionsOpenings = true;
                            ecData.SetLocalPlacement(placementSetter.LocalPlacement);

                            ElementId categoryId = CategoryUtil.GetSafeCategoryId(roof);

                            BodyExporterOptions  bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow);
                            BodyData             bodyData            = null;
                            IFCAnyHandle         prodRep             = null;
                            IList <IFCAnyHandle> representations     = new List <IFCAnyHandle>();
                            IList <ElementId>    materialIds         = new List <ElementId>();

                            if (!exportByComponents)
                            {
                                prodRep = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, roof,
                                                                                                     categoryId, geometryElement, bodyExporterOptions, null, ecData, out bodyData);
                                if (bodyData != null && bodyData.MaterialIds != null)
                                {
                                    materialIds = bodyData.MaterialIds;
                                }
                            }
                            else
                            {
                                prodRep = RepresentationUtil.CreateProductDefinitionShapeWithoutBodyRep(exporterIFC, roof, categoryId, geometryElement, representations);
                            }

                            if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodRep))
                            {
                                ecData.ClearOpenings();
                                return;
                            }

                            bool exportSlab = ((ecData.ScaledLength > MathUtil.Eps() || exportByComponents) &&
                                               roofExportType.ExportInstance == IFCEntityType.IfcRoof && !exportRoofAsSingleGeometry);

                            string       guid           = GUIDUtil.CreateGUID(roof);
                            IFCAnyHandle ownerHistory   = ExporterCacheManager.OwnerHistoryHandle;
                            IFCAnyHandle localPlacement = ecData.GetLocalPlacement();

                            IFCAnyHandle roofHnd = IFCInstanceExporter.CreateGenericIFCEntity(
                                roofExportType, exporterIFC, roof, guid, ownerHistory,
                                localPlacement, exportSlab ? null : prodRep);

                            IFCAnyHandle typeHnd = ExporterUtil.CreateGenericTypeFromElement(roof,
                                                                                             roofExportType, file, ownerHistory, roofExportType.ValidatedPredefinedType,
                                                                                             productWrapper);
                            ExporterCacheManager.TypeRelationsCache.Add(typeHnd, roofHnd);

                            productWrapper.AddElement(roof, roofHnd, placementSetter.LevelInfo, ecData, true, roofExportType);

                            if (!(roof is RoofBase))
                            {
                                CategoryUtil.CreateMaterialAssociation(exporterIFC, roofHnd, materialIds);
                            }

                            if (exportByComponents && (exportSlab || exportRoofAsSingleGeometry))
                            {
                                IFCAnyHandle hostShapeRepFromParts = PartExporter.ExportHostPartAsShapeAspects(exporterIFC, roof, prodRep,
                                                                                                               productWrapper, placementSetter, localPlacement, ElementId.InvalidElementId, layersetInfo, ecData);
                            }

                            Transform offsetTransform = (bodyData != null) ? bodyData.OffsetTransform : Transform.Identity;

                            if (exportSlab)
                            {
                                string       slabGUID = GUIDUtil.CreateSubElementGUID(roof, (int)IFCRoofSubElements.RoofSlabStart);
                                IFCAnyHandle slabLocalPlacementHnd = ExporterUtil.CopyLocalPlacement(file, localPlacement);
                                string       slabName = IFCAnyHandleUtil.GetStringAttribute(roofHnd, "Name") + ":1";

                                IFCAnyHandle slabHnd = IFCInstanceExporter.CreateSlab(exporterIFC, roof, slabGUID, ownerHistory,
                                                                                      slabLocalPlacementHnd, prodRep, slabRoofPredefinedType);
                                IFCAnyHandleUtil.OverrideNameAttribute(slabHnd, slabName);

                                OpeningUtil.CreateOpeningsIfNecessary(slabHnd, roof, ecData, offsetTransform,
                                                                      exporterIFC, slabLocalPlacementHnd, placementSetter, productWrapper);

                                ExporterUtil.RelateObject(exporterIFC, roofHnd, slabHnd);
                                IFCExportInfoPair slabRoofExportType = new IFCExportInfoPair(IFCEntityType.IfcSlab, slabRoofPredefinedType);

                                productWrapper.AddElement(null, slabHnd, placementSetter.LevelInfo, ecData, false, slabRoofExportType);

                                // Create type
                                IFCAnyHandle slabRoofTypeHnd = ExporterUtil.CreateGenericTypeFromElement(roof, slabRoofExportType, exporterIFC.GetFile(), ownerHistory, slabRoofPredefinedType, productWrapper);
                                ExporterCacheManager.TypeRelationsCache.Add(slabRoofTypeHnd, slabHnd);

                                ExporterUtil.AddIntoComplexPropertyCache(slabHnd, layersetInfo);
                                // For earlier than IFC4 version of IFC export, the material association will be done at the Roof host level with MaterialSetUsage
                                // This one is only for IFC4 and above
                                if ((roof is RoofBase) && !ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4)
                                {
                                    if (layersetInfo != null && !IFCAnyHandleUtil.IsNullOrHasNoValue(layersetInfo.MaterialLayerSetHandle))
                                    {
                                        CategoryUtil.CreateMaterialAssociation(exporterIFC, slabHnd, layersetInfo.MaterialLayerSetHandle);
                                    }
                                    else if (bodyData != null)
                                    {
                                        CategoryUtil.CreateMaterialAssociation(exporterIFC, slabHnd, bodyData.MaterialIds);
                                    }
                                }
                            }
                            else
                            {
                                OpeningUtil.CreateOpeningsIfNecessary(roofHnd, roof, ecData, offsetTransform,
                                                                      exporterIFC, localPlacement, placementSetter, productWrapper);

                                // For earlier than IFC4 version of IFC export, the material association will be done at the Roof host level with MaterialSetUsage
                                // This one is only for IFC4 and above
                                if ((roof is RoofBase) && !ExporterCacheManager.ExportOptionsCache.ExportAsOlderThanIFC4)
                                {
                                    if (layersetInfo != null && !IFCAnyHandleUtil.IsNullOrHasNoValue(layersetInfo.MaterialLayerSetHandle))
                                    {
                                        CategoryUtil.CreateMaterialAssociation(exporterIFC, roofHnd, layersetInfo.MaterialLayerSetHandle);
                                    }
                                    else if (layersetInfo != null && layersetInfo.MaterialIds != null)
                                    {
                                        materialIds = layersetInfo.MaterialIds.Select(x => x.m_baseMatId).ToList();
                                        CategoryUtil.CreateMaterialAssociation(exporterIFC, roofHnd, materialIds);
                                    }
                                }
                            }
                        }
                        tr.Commit();
                    }
                }
            }
        }
Пример #39
0
        /// <summary>
        /// Exports a ramp to IfcRamp, without decomposing into separate runs and landings.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="ifcEnumType">The ramp type.</param>
        /// <param name="ramp">The ramp element.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="numFlights">The number of flights for a multistory ramp.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        public static void ExportRamp(ExporterIFC exporterIFC, string ifcEnumType, Element ramp, GeometryElement geometryElement,
                                      int numFlights, ProductWrapper productWrapper)
        {
            if (ramp == null || geometryElement == null)
            {
                return;
            }

            IFCFile file = exporterIFC.GetFile();

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                using (PlacementSetter placementSetter = PlacementSetter.Create(exporterIFC, ramp))
                {
                    using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                    {
                        ecData.SetLocalPlacement(placementSetter.LocalPlacement);
                        ecData.ReuseLocalPlacement = false;

                        GeometryElement rampGeom = GeometryUtil.GetOneLevelGeometryElement(geometryElement, numFlights);

                        BodyData  bodyData;
                        ElementId categoryId = CategoryUtil.GetSafeCategoryId(ramp);

                        BodyExporterOptions bodyExporterOptions = new BodyExporterOptions();
                        IFCAnyHandle        representation      = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC,
                                                                                                                             ramp, categoryId, rampGeom, bodyExporterOptions, null, ecData, out bodyData);

                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(representation))
                        {
                            ecData.ClearOpenings();
                            return;
                        }

                        string       containedRampGuid           = GUIDUtil.CreateSubElementGUID(ramp, (int)IFCRampSubElements.ContainedRamp);
                        IFCAnyHandle ownerHistory                = exporterIFC.GetOwnerHistoryHandle();
                        string       rampName                    = NamingUtil.GetNameOverride(ramp, NamingUtil.GetIFCName(ramp));
                        string       rampDescription             = NamingUtil.GetDescriptionOverride(ramp, null);
                        string       rampObjectType              = NamingUtil.GetObjectTypeOverride(ramp, NamingUtil.CreateIFCObjectName(exporterIFC, ramp));
                        IFCAnyHandle containedRampLocalPlacement = ExporterUtil.CreateLocalPlacement(file, ecData.GetLocalPlacement(), null);
                        string       elementTag                  = NamingUtil.GetTagOverride(ramp, NamingUtil.CreateIFCElementId(ramp));
                        string       rampType                    = GetIFCRampType(ifcEnumType);

                        List <IFCAnyHandle> components = new List <IFCAnyHandle>();
                        IList <IFCExtrusionCreationData> componentExtrusionData = new List <IFCExtrusionCreationData>();
                        IFCAnyHandle containedRampHnd = IFCInstanceExporter.CreateRamp(file, containedRampGuid, ownerHistory, rampName,
                                                                                       rampDescription, rampObjectType, containedRampLocalPlacement, representation, elementTag, rampType);
                        components.Add(containedRampHnd);
                        componentExtrusionData.Add(ecData);
                        //productWrapper.AddElement(containedRampHnd, placementSetter.LevelInfo, ecData, false);
                        CategoryUtil.CreateMaterialAssociations(exporterIFC, containedRampHnd, bodyData.MaterialIds);

                        string       guid           = GUIDUtil.CreateGUID(ramp);
                        IFCAnyHandle localPlacement = ecData.GetLocalPlacement();

                        IFCAnyHandle rampHnd = IFCInstanceExporter.CreateRamp(file, guid, ownerHistory, rampName,
                                                                              rampDescription, rampObjectType, localPlacement, null, elementTag, rampType);

                        productWrapper.AddElement(ramp, rampHnd, placementSetter.LevelInfo, ecData, true);

                        StairRampContainerInfo stairRampInfo = new StairRampContainerInfo(rampHnd, components, localPlacement);
                        ExporterCacheManager.StairRampContainerInfoCache.AddStairRampContainerInfo(ramp.Id, stairRampInfo);

                        ExportMultistoryRamp(exporterIFC, ramp, numFlights, rampHnd, components, componentExtrusionData, placementSetter,
                                             productWrapper);
                    }
                    tr.Commit();
                }
            }
        }
        private static HandleAndAnalyzer CreateExtrusionWithClippingBase(ExporterIFC exporterIFC, Element element,
            ElementId catId, IList<Solid> solids, Plane plane, XYZ projDir, IFCRange range, out bool completelyClipped, out HashSet<ElementId> materialIds)
        {
            IFCFile file = exporterIFC.GetFile();
            bool mustUseTessellation = false;

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                completelyClipped = false;
                materialIds = new HashSet<ElementId>();
                HandleAndAnalyzer retVal = new HandleAndAnalyzer();
                HashSet<IFCAnyHandle> extrusionBodyItems = new HashSet<IFCAnyHandle>();
                HashSet<IFCAnyHandle> extrusionBooleanBodyItems = new HashSet<IFCAnyHandle>();
                HashSet<IFCAnyHandle> extrusionClippingBodyItems = new HashSet<IFCAnyHandle>();
                foreach (Solid solid in solids)
                {
                    bool hasClippingResult = false;
                    bool hasBooleanResult = false;
                    ElementId materialId = ElementId.InvalidElementId;
                    HandleAndAnalyzer currRetVal = CreateExtrusionWithClippingAndOpening(exporterIFC, element, catId, solid, plane, projDir, range,
                        out completelyClipped, out hasClippingResult, out hasBooleanResult, out materialId);

                    if (currRetVal != null && currRetVal.Handle != null)
                    {
                        // If any of the solid is of the type of Clipping or Boolean and export is for Reference View, exit the loop and collect the geometries entirely
                        //   for TriangulatedFaceSet
                        if (ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView && (hasClippingResult || hasBooleanResult))
                        {
                            mustUseTessellation = true;
                            break;
                        }

                        materialIds.Add(materialId);
                        IFCAnyHandle repHandle = currRetVal.Handle;
                        if (hasBooleanResult) // if both have boolean and clipping result, use boolean one.
                            extrusionBooleanBodyItems.Add(repHandle);
                        else if (hasClippingResult)
                            extrusionClippingBodyItems.Add(repHandle);
                        else
                            extrusionBodyItems.Add(repHandle);
                    }
                    else
                    {
                        tr.RollBack();

                        // TODO: include this cleanup in RollBack(), to avoid issues.
                        ExporterCacheManager.MaterialIdToStyleHandleCache.RemoveInvalidHandles(materialIds, IFCEntityType.IfcSurfaceStyle);
                        ExporterCacheManager.PresentationStyleAssignmentCache.RemoveInvalidHandles(materialIds);
                        return retVal;
                    }

                    // currRetVal will only have one extrusion.  Use the analyzer from the "last" extrusion.  Should only really be used for one extrusion.
                    retVal.Analyzer = currRetVal.Analyzer;
                    retVal.BaseExtrusions.Add(currRetVal.BaseExtrusions[0]);
                }

                IFCAnyHandle contextOfItemsBody = exporterIFC.Get3DContextHandle("Body");

                // Handle Tessellation here for Reference View export. If all are extrusions, it should not get in here
                if (mustUseTessellation)
                {
                    BodyExporterOptions options = new BodyExporterOptions(true);
                    Document document = element.Document;
                    ElementId materialId = ElementId.InvalidElementId;
                    materialIds.Clear();
                    extrusionBodyItems.Clear();

                    foreach (Solid solid in solids)
                    {
                        IFCAnyHandle triangulatedBodyItem = BodyExporter.ExportBodyAsTriangulatedFaceSet(exporterIFC, element, options, solid);
                        if (!IFCAnyHandleUtil.IsNullOrHasNoValue(triangulatedBodyItem))
                            extrusionBodyItems.Add(triangulatedBodyItem);
                        materialId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(solid, exporterIFC, element);
                        materialIds.Add(materialId);
                        BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, document, triangulatedBodyItem, materialId);
                    }
                    retVal.Handle = RepresentationUtil.CreateTessellatedRep(exporterIFC, element, catId, contextOfItemsBody, extrusionBodyItems, null);
                    retVal.ShapeRepresentationType = ShapeRepresentationType.Tessellation;
                }
                else
                {
                    if (extrusionBodyItems.Count > 0 && (extrusionClippingBodyItems.Count == 0 && extrusionBooleanBodyItems.Count == 0))
                    {
                        retVal.Handle = RepresentationUtil.CreateSweptSolidRep(exporterIFC, element, catId, contextOfItemsBody,
                            extrusionBodyItems, null);
                        retVal.ShapeRepresentationType = ShapeRepresentationType.SweptSolid;
                    }
                    else if (extrusionClippingBodyItems.Count > 0 && (extrusionBodyItems.Count == 0 && extrusionBooleanBodyItems.Count == 0))
                    {
                        retVal.Handle = RepresentationUtil.CreateClippingRep(exporterIFC, element, catId, contextOfItemsBody,
                            extrusionClippingBodyItems);
                        retVal.ShapeRepresentationType = ShapeRepresentationType.Clipping;
                    }
                    else if (extrusionBooleanBodyItems.Count > 0 && (extrusionBodyItems.Count == 0 && extrusionClippingBodyItems.Count == 0))
                    {
                        retVal.Handle = RepresentationUtil.CreateCSGRep(exporterIFC, element, catId, contextOfItemsBody,
                            extrusionBooleanBodyItems);
                        retVal.ShapeRepresentationType = ShapeRepresentationType.CSG;
                    }
                    else
                    {
                        IFCAnyHandle finalBodyItemHnd = null;

                        ICollection<IFCAnyHandle> booleanBodyItems = extrusionClippingBodyItems.Union<IFCAnyHandle>(extrusionBooleanBodyItems).ToList();

                        finalBodyItemHnd = booleanBodyItems.ElementAt(0);
                        booleanBodyItems.Remove(finalBodyItemHnd);

                        // union non-boolean result first with a boolean result
                        foreach (IFCAnyHandle bodyRep in extrusionBodyItems)
                        {
                            finalBodyItemHnd = IFCInstanceExporter.CreateBooleanResult(exporterIFC.GetFile(), IFCBooleanOperator.Union,
                                 finalBodyItemHnd, bodyRep);
                        }

                        foreach (IFCAnyHandle bodyRep in booleanBodyItems)
                        {
                            finalBodyItemHnd = IFCInstanceExporter.CreateBooleanResult(exporterIFC.GetFile(), IFCBooleanOperator.Union,
                                 finalBodyItemHnd, bodyRep);
                        }

                        extrusionBodyItems.Clear();
                        extrusionBodyItems.Add(finalBodyItemHnd);

                        retVal.Handle = RepresentationUtil.CreateCSGRep(exporterIFC, element, catId, contextOfItemsBody,
                            extrusionBodyItems);
                        retVal.ShapeRepresentationType = ShapeRepresentationType.CSG;
                    }
                }

                tr.Commit();
                return retVal;
            }
        }
Пример #41
0
        /// <summary>
        /// Exports a roof to IfcRoof.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="ifcEnumType">The roof type.</param>
        /// <param name="roof">The roof element.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        public static void ExportRoof(ExporterIFC exporterIFC, string ifcEnumType, Element roof, GeometryElement geometryElement,
                                      ProductWrapper productWrapper)
        {
            if (roof == null || geometryElement == null)
            {
                return;
            }

            IFCFile file = exporterIFC.GetFile();

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                using (PlacementSetter placementSetter = PlacementSetter.Create(exporterIFC, roof))
                {
                    using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                    {
                        // If the roof is an in-place family, we will allow any arbitrary orientation.  While this may result in some
                        // in-place "cubes" exporting with the wrong direction, it is unlikely that an in-place family would be
                        // used for this reason in the first place.
                        ecData.PossibleExtrusionAxes   = (roof is FamilyInstance) ? IFCExtrusionAxes.TryXYZ : IFCExtrusionAxes.TryZ;
                        ecData.AreInnerRegionsOpenings = true;
                        ecData.SetLocalPlacement(placementSetter.LocalPlacement);

                        ElementId categoryId = CategoryUtil.GetSafeCategoryId(roof);

                        BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true);
                        BodyData            bodyData;
                        IFCAnyHandle        representation = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, roof,
                                                                                                                        categoryId, geometryElement, bodyExporterOptions, null, ecData, out bodyData);

                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(representation))
                        {
                            ecData.ClearOpenings();
                            return;
                        }

                        bool exportSlab = ecData.ScaledLength > MathUtil.Eps();

                        string       guid            = GUIDUtil.CreateGUID(roof);
                        IFCAnyHandle ownerHistory    = exporterIFC.GetOwnerHistoryHandle();
                        string       roofName        = NamingUtil.GetNameOverride(roof, NamingUtil.GetIFCName(roof));
                        string       roofDescription = NamingUtil.GetDescriptionOverride(roof, null);
                        string       roofObjectType  = NamingUtil.GetObjectTypeOverride(roof, NamingUtil.CreateIFCObjectName(exporterIFC, roof));
                        IFCAnyHandle localPlacement  = ecData.GetLocalPlacement();
                        string       elementTag      = NamingUtil.GetTagOverride(roof, NamingUtil.CreateIFCElementId(roof));
                        string       roofType        = GetIFCRoofType(ifcEnumType);
                        roofType = IFCValidateEntry.GetValidIFCType(roof, ifcEnumType);

                        IFCAnyHandle roofHnd = IFCInstanceExporter.CreateRoof(file, guid, ownerHistory, roofName, roofDescription,
                                                                              roofObjectType, localPlacement, exportSlab ? null : representation, elementTag, roofType);

                        productWrapper.AddElement(roof, roofHnd, placementSetter.LevelInfo, ecData, true);

                        // will export its host object materials later if it is a roof
                        if (!(roof is RoofBase))
                        {
                            CategoryUtil.CreateMaterialAssociations(exporterIFC, roofHnd, bodyData.MaterialIds);
                        }

                        if (exportSlab)
                        {
                            string       slabGUID = GUIDUtil.CreateSubElementGUID(roof, (int)IFCRoofSubElements.RoofSlabStart);
                            string       slabName = roofName + ":1";
                            IFCAnyHandle slabLocalPlacementHnd = ExporterUtil.CopyLocalPlacement(file, localPlacement);

                            IFCAnyHandle slabHnd = IFCInstanceExporter.CreateSlab(file, slabGUID, ownerHistory, slabName,
                                                                                  roofDescription, roofObjectType, slabLocalPlacementHnd, representation, elementTag, "ROOF");

                            Transform offsetTransform = (bodyData != null) ? bodyData.OffsetTransform : Transform.Identity;
                            OpeningUtil.CreateOpeningsIfNecessary(slabHnd, roof, ecData, offsetTransform,
                                                                  exporterIFC, slabLocalPlacementHnd, placementSetter, productWrapper);

                            ExporterUtil.RelateObject(exporterIFC, roofHnd, slabHnd);

                            productWrapper.AddElement(null, slabHnd, placementSetter.LevelInfo, ecData, false);
                            CategoryUtil.CreateMaterialAssociations(exporterIFC, slabHnd, bodyData.MaterialIds);
                        }
                    }
                    tr.Commit();
                }
            }
        }
        /// <summary>
        /// Exports an element as IFC covering.
        /// </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 ExportCovering(ExporterIFC exporterIFC, Element element, GeometryElement geomElem, string ifcEnumType, ProductWrapper productWrapper)
        {
            bool exportParts = PartExporter.CanExportParts(element);
            if (exportParts && !PartExporter.CanExportElementInPartExport(element, element.LevelId, false))
                return;

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

            using (IFCTransaction transaction = new IFCTransaction(file))
            {
                using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element))
                {
                    using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                    {
                        ElementId categoryId = CategoryUtil.GetSafeCategoryId(element);

                        IFCAnyHandle prodRep = null;
                        if (!exportParts)
                        {
                            ecData.SetLocalPlacement(setter.LocalPlacement);
                            ecData.PossibleExtrusionAxes = IFCExtrusionAxes.TryZ;

                            BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true);
                            prodRep = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, element,
                                categoryId, geomElem, bodyExporterOptions, null, ecData, true);
                            if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodRep))
                            {
                                ecData.ClearOpenings();
                                return;
                            }
                        }

                        // We will use the category of the element to set a default value for the covering.
                        string defaultCoveringEnumType = null;

                        if (categoryId == new ElementId(BuiltInCategory.OST_Ceilings))
                            defaultCoveringEnumType = "CEILING";
                        else if (categoryId == new ElementId(BuiltInCategory.OST_Floors))
                            defaultCoveringEnumType = "FLOORING";
                        else if (categoryId == new ElementId(BuiltInCategory.OST_Roofs))
                            defaultCoveringEnumType = "ROOFING";

                        string instanceGUID = GUIDUtil.CreateGUID(element);
                        string instanceName = NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element));
                        string instanceDescription = NamingUtil.GetDescriptionOverride(element, null);
                        string instanceObjectType = NamingUtil.GetObjectTypeOverride(element, exporterIFC.GetFamilyName());
                        string instanceTag = NamingUtil.GetTagOverride(element, NamingUtil.CreateIFCElementId(element));
                        string coveringType = IFCValidateEntry.GetValidIFCType(element, ifcEnumType, defaultCoveringEnumType);

                        IFCAnyHandle covering = IFCInstanceExporter.CreateCovering(file, instanceGUID, ExporterCacheManager.OwnerHistoryHandle,
                            instanceName, instanceDescription, instanceObjectType, setter.LocalPlacement, prodRep, instanceTag, coveringType);

                        if (exportParts)
                        {
                            PartExporter.ExportHostPart(exporterIFC, element, covering, productWrapper, setter, setter.LocalPlacement, null);
                        }

                        bool containInSpace = false;
                        IFCAnyHandle localPlacementToUse = setter.LocalPlacement;

                        // Ceiling containment in Space is generally required and not specific to any view
                        if (ExporterCacheManager.CeilingSpaceRelCache.ContainsKey(element.Id))
                        {
                            IList<ElementId> roomlist = ExporterCacheManager.CeilingSpaceRelCache[element.Id];

                            // Process Ceiling to be contained in a Space only when it is exactly bounding one Space
                            if (roomlist.Count == 1)
                            {
                                productWrapper.AddElement(element, covering, setter, null, false);

                                // Modify the Ceiling placement to be relative to the Space that it bounds 
                                IFCAnyHandle roomPlacement = IFCAnyHandleUtil.GetObjectPlacement(ExporterCacheManager.SpaceInfoCache.FindSpaceHandle(roomlist[0]));
                                Transform relTrf = ExporterIFCUtils.GetRelativeLocalPlacementOffsetTransform(roomPlacement, localPlacementToUse);
                                Transform inverseTrf = relTrf.Inverse;
                                IFCAnyHandle relLocalPlacement = ExporterUtil.CreateAxis2Placement3D(file, inverseTrf.Origin, inverseTrf.BasisZ, inverseTrf.BasisX);
                                IFCAnyHandleUtil.SetAttribute(localPlacementToUse, "PlacementRelTo", roomPlacement);
                                GeometryUtil.SetRelativePlacement(localPlacementToUse, relLocalPlacement);

                                ExporterCacheManager.SpaceInfoCache.RelateToSpace(roomlist[0], covering);
                                containInSpace = true;
                            }
                        }

                        // if not contained in Space, assign it to default containment in Level
                        if (!containInSpace)
                            productWrapper.AddElement(element, covering, setter, null, true);

                        if (!exportParts)
                        {
                            Ceiling ceiling = element as Ceiling;
                            if (ceiling != null)
                            {
                                HostObjectExporter.ExportHostObjectMaterials(exporterIFC, ceiling, covering,
                                    geomElem, productWrapper, ElementId.InvalidElementId, Toolkit.IFCLayerSetDirection.Axis3, null);
                            }
                            else
                            {
                                ElementId matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geomElem, exporterIFC, element);
                                CategoryUtil.CreateMaterialAssociation(exporterIFC, covering, matId);
                            }
                        }

                        OpeningUtil.CreateOpeningsIfNecessary(covering, element, ecData, null,
                            exporterIFC, ecData.GetLocalPlacement(), setter, productWrapper);
                    }
                }
                transaction.Commit();
            }
        }
Пример #43
0
        private static IFCAnyHandle TryToCreateAsExtrusion(ExporterIFC exporterIFC, 
            Wall wallElement, 
            IList<IList<IFCConnectedWallData>> connectedWalls,
            IList<Solid> solids,
            IList<Mesh> meshes,
            double baseWallElevation, 
            ElementId catId, 
            Curve baseCurve, 
            Curve trimmedCurve,
            Plane wallLCS, 
            double scaledDepth, 
            IFCRange zSpan, 
            IFCRange range, 
            PlacementSetter setter,
            out IList<IFCExtrusionData> cutPairOpenings, 
            out bool isCompletelyClipped, 
            out double scaledFootprintArea, 
            out double scaledLength)
        {
            cutPairOpenings = new List<IFCExtrusionData>();

            IFCAnyHandle bodyRep;
            scaledFootprintArea = 0;

            double unscaledLength = trimmedCurve != null ? trimmedCurve.Length : 0;
            scaledLength = UnitUtil.ScaleLength(unscaledLength);

            XYZ localOrig = wallLCS.Origin;

            // Check to see if the wall has geometry given the specified range.
            if (!WallHasGeometryToExport(wallElement, solids, meshes, range, out isCompletelyClipped))
                return null;

            // This is our major check here that goes into internal code.  If we have enough information to faithfully reproduce
            // the wall as an extrusion with clippings and openings, we will continue.  Otherwise, export it as a BRep.
            if (!CanExportWallGeometryAsExtrusion(wallElement, range))
                return null;

            // extrusion direction.
            XYZ extrusionDir = GetWallHeightDirection(wallElement);

            // create extrusion boundary.
            bool alwaysThickenCurve = IsWallBaseRectangular(wallElement, trimmedCurve);
            
            double unscaledWidth = wallElement.Width;
            IList<CurveLoop> boundaryLoops = GetBoundaryLoopsFromWall(exporterIFC, wallElement, alwaysThickenCurve, trimmedCurve, unscaledWidth);
            if (boundaryLoops == null || boundaryLoops.Count == 0)
                    return null;

            double fullUnscaledLength = baseCurve.Length;
            double unscaledFootprintArea = ExporterIFCUtils.ComputeAreaOfCurveLoops(boundaryLoops);
            scaledFootprintArea = UnitUtil.ScaleArea(unscaledFootprintArea);
            // We are going to do a little sanity check here.  If the scaledFootprintArea is significantly less than the 
            // width * length of the wall footprint, we probably calculated the area wrong, and will abort.
            // This could occur because of a door or window that cuts a corner of the wall (i.e., has no wall material on one side).
            // We want the scaledFootprintArea to be at least (95% of approximateBaseArea - 2 * side wall area).  
            // The "side wall area" is an approximate value that takes into account potential wall joins.  
            // This prevents us from doing extra work for many small walls because of joins.  We'll allow 1' (~30 cm) per side for this.
            double approximateUnscaledBaseArea = unscaledWidth * fullUnscaledLength;
            if (unscaledFootprintArea < (approximateUnscaledBaseArea * .95 - 2 * unscaledWidth))
            {
                // Can't handle the case where we don't have a simple extrusion to begin with.
                if (!alwaysThickenCurve)
                    return null;

                boundaryLoops = GetBoundaryLoopsFromBaseCurve(wallElement, connectedWalls, baseCurve, trimmedCurve, unscaledWidth, scaledDepth);
                if (boundaryLoops == null || boundaryLoops.Count == 0)
                return null;
            }

            // origin gets scaled later.
            double baseWallZOffset = localOrig[2] - ((range == null) ? baseWallElevation : Math.Min(range.Start, baseWallElevation));
            XYZ modifiedSetterOffset = new XYZ(0, 0, setter.Offset + baseWallZOffset);

            IFCAnyHandle baseBodyItemHnd = ExtrusionExporter.CreateExtrudedSolidFromCurveLoop(exporterIFC, null, boundaryLoops, wallLCS,
                extrusionDir, scaledDepth);
            if (IFCAnyHandleUtil.IsNullOrHasNoValue(baseBodyItemHnd))
                return null;

            IFCAnyHandle bodyItemHnd = AddClippingsToBaseExtrusion(exporterIFC, wallElement,
               modifiedSetterOffset, range, zSpan, baseBodyItemHnd, out cutPairOpenings);
            if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyItemHnd))
                return null;
            bool hasClipping = bodyItemHnd.Id != baseBodyItemHnd.Id;

            ElementId matId = HostObjectExporter.GetFirstLayerMaterialId(wallElement);
            IFCAnyHandle styledItemHnd = BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, wallElement.Document,
                baseBodyItemHnd, matId);

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

            // Check whether wall has opening. If it has, exporting it in the Reference View will need to be in a tessellated geometry that includes the opening cut
            IList<IFCOpeningData> openingDataList = ExporterIFCUtils.GetOpeningData(exporterIFC, wallElement, wallLCS, range);
            bool wallHasOpening = openingDataList.Count > 0;
            BodyExporterOptions options = new BodyExporterOptions(true);

            IFCAnyHandle contextOfItemsBody = exporterIFC.Get3DContextHandle("Body");
            if (!hasClipping)
            {
                // Check whether wall has opening. If it has, exporting it in Reference View will need to be in a tesselated geometry that includes the opening cut
                if (ExporterUtil.IsReferenceView() && wallHasOpening)
                {
                    List<GeometryObject> geomList = new List<GeometryObject>();
                    bodyItems.Clear();       // Since we will change the geometry, clear existing extrusion data first
                    if (solids.Count > 0)
                        foreach (GeometryObject solid in solids)
                            geomList.Add(solid);
                    if (meshes.Count > 0)
                        foreach (GeometryObject mesh in meshes)
                            geomList.Add(mesh);
                    foreach (GeometryObject geom in geomList)
                    {
                        IFCAnyHandle triangulatedBodyItem = BodyExporter.ExportBodyAsTriangulatedFaceSet(exporterIFC, wallElement, options, geom);
                        if (!IFCAnyHandleUtil.IsNullOrHasNoValue(triangulatedBodyItem)) 
                            bodyItems.Add(triangulatedBodyItem);
                    }
                    bodyRep = RepresentationUtil.CreateTessellatedRep(exporterIFC, wallElement, catId, contextOfItemsBody, bodyItems, null);
                }
                else
                    bodyRep = RepresentationUtil.CreateSweptSolidRep(exporterIFC, wallElement, catId, contextOfItemsBody, bodyItems, null);
            }
            else
            {
                // Create TessellatedRep geometry if it is Reference View.
                if (ExporterUtil.IsReferenceView())
                {
                    List<GeometryObject> geomList = new List<GeometryObject>();
                    // The native function AddClippingsToBaseExtrusion will create the IfcBooleanClippingResult entity and therefore here we need to delete it
                    foreach (IFCAnyHandle item in bodyItems)
                    {
                        item.Dispose();     //Still DOES NOT work, the IfcBooleanClippingResult is still orphaned in the IFC file!
                    }
                    bodyItems.Clear();       // Since we will change the geometry, clear existing extrusion data first

                    if (solids.Count > 0)
                        foreach (GeometryObject solid in solids)
                            geomList.Add(solid);
                    if (meshes.Count > 0)
                        foreach (GeometryObject mesh in meshes)
                            geomList.Add(mesh);
                    foreach (GeometryObject geom in geomList)
                    {
                        IFCAnyHandle triangulatedBodyItem = BodyExporter.ExportBodyAsTriangulatedFaceSet(exporterIFC, wallElement, options, geom);
                        if (!IFCAnyHandleUtil.IsNullOrHasNoValue(triangulatedBodyItem)) 
                            bodyItems.Add(triangulatedBodyItem);
                    }
                    bodyRep = RepresentationUtil.CreateTessellatedRep(exporterIFC, wallElement, catId, contextOfItemsBody, bodyItems, null);
                }
                else
                    bodyRep = RepresentationUtil.CreateClippingRep(exporterIFC, wallElement, catId, contextOfItemsBody, bodyItems);
            }

            return bodyRep;
        }
        /// <summary>
        /// Exports an element as building element proxy.
        /// </summary>
        /// <remarks>
        /// This function is called from the Export function, but can also be called directly if you do not
        /// want CreateInternalPropertySets to be called.
        /// </remarks>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="element">The element.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        /// <returns>The handle if created, null otherwise.</returns>
        public static IFCAnyHandle ExportBuildingElementProxy(ExporterIFC exporterIFC, Element element,
                                                              GeometryElement geometryElement, ProductWrapper productWrapper)
        {
            if (element == null || geometryElement == null)
            {
                return(null);
            }

            // Check the intended IFC entity or type name is in the exclude list specified in the UI
            Common.Enums.IFCEntityType elementClassTypeEnum;
            if (Enum.TryParse <Common.Enums.IFCEntityType>("IfcBuildingElementProxy", out elementClassTypeEnum))
            {
                if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum))
                {
                    return(null);
                }
            }

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

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                using (PlacementSetter placementSetter = PlacementSetter.Create(exporterIFC, element))
                {
                    using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                    {
                        ecData.SetLocalPlacement(placementSetter.LocalPlacement);

                        ElementId categoryId = CategoryUtil.GetSafeCategoryId(element);

                        BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow);
                        IFCAnyHandle        representation      = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, element,
                                                                                                                             categoryId, geometryElement, bodyExporterOptions, null, ecData, true);

                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(representation))
                        {
                            ecData.ClearOpenings();
                            return(null);
                        }

                        string       guid            = GUIDUtil.CreateGUID(element);
                        IFCAnyHandle ownerHistory    = ExporterCacheManager.OwnerHistoryHandle;
                        string       revitObjectType = exporterIFC.GetFamilyName();
                        string       name            = NamingUtil.GetNameOverride(element, revitObjectType);
                        string       description     = NamingUtil.GetDescriptionOverride(element, null);
                        string       objectType      = NamingUtil.GetObjectTypeOverride(element, revitObjectType);

                        IFCAnyHandle localPlacement = ecData.GetLocalPlacement();
                        string       elementTag     = NamingUtil.GetTagOverride(element, NamingUtil.CreateIFCElementId(element));

                        buildingElementProxy = IFCInstanceExporter.CreateBuildingElementProxy(file, guid,
                                                                                              ownerHistory, name, description, objectType, localPlacement, representation, elementTag, null);

                        productWrapper.AddElement(element, buildingElementProxy, placementSetter.LevelInfo, ecData, true);
                    }
                    tr.Commit();
                }
            }

            return(buildingElementProxy);
        }
Пример #45
0
        /// <summary>
        /// Exports curtain object as one Brep.
        /// </summary>
        /// <param name="allSubElements">
        /// Collection of elements contained in the host curtain element.
        /// </param>
        /// <param name="wallElement">
        /// The curtain wall element.
        /// </param>
        /// <param name="exporterIFC">
        /// The ExporterIFC object.
        /// </param>
        /// <param name="setter">
        /// The PlacementSetter object.
        /// </param>
        /// <param name="localPlacement">
        /// The local placement handle.
        /// </param>
        /// <returns>
        /// The handle.
        /// </returns>
        public static IFCAnyHandle ExportCurtainObjectCommonAsOneBRep(ICollection <ElementId> allSubElements, Element wallElement,
                                                                      ExporterIFC exporterIFC)
        {
            IFCAnyHandle prodDefRep = null;
            Document     document   = wallElement.Document;
            double       eps        = UnitUtil.ScaleLength(document.Application.VertexTolerance);

            IFCFile      file           = exporterIFC.GetFile();
            IFCAnyHandle contextOfItems = exporterIFC.Get3DContextHandle("Body");

            IFCGeometryInfo info = IFCGeometryInfo.CreateFaceGeometryInfo(eps);

            ISet <IFCAnyHandle> bodyItems = new HashSet <IFCAnyHandle>();

            // Want to make sure we don't accidentally add a mullion or curtain line more than once.
            HashSet <ElementId> alreadyVisited = new HashSet <ElementId>();
            bool    useFallbackBREP            = true;
            Options geomOptions = GeometryUtil.GetIFCExportGeometryOptions();

            foreach (ElementId subElemId in allSubElements)
            {
                Element         subElem  = wallElement.Document.GetElement(subElemId);
                GeometryElement geomElem = subElem.get_Geometry(geomOptions);
                if (geomElem == null)
                {
                    continue;
                }

                if (alreadyVisited.Contains(subElem.Id))
                {
                    continue;
                }
                alreadyVisited.Add(subElem.Id);


                // Export tessellated geometry when IFC4 Reference View is selected
                if (ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView || ExporterCacheManager.ExportOptionsCache.ExportAs4General)
                {
                    BodyExporterOptions  bodyExporterOptions = new BodyExporterOptions(false, ExportOptionsCache.ExportTessellationLevel.ExtraLow);
                    IList <IFCAnyHandle> triFaceSet          = BodyExporter.ExportBodyAsTessellatedFaceSet(exporterIFC, subElem, bodyExporterOptions, geomElem);
                    if (triFaceSet != null && triFaceSet.Count > 0)
                    {
                        foreach (IFCAnyHandle triFaceSetItem in triFaceSet)
                        {
                            bodyItems.Add(triFaceSetItem);
                        }
                        useFallbackBREP = false; // no need to do Brep since it is successful
                    }
                }
                // Export AdvancedFace before use fallback BREP
                else if (ExporterCacheManager.ExportOptionsCache.ExportAs4DesignTransferView)
                {
                    IFCAnyHandle advancedBRep = BodyExporter.ExportBodyAsAdvancedBrep(exporterIFC, subElem, geomElem);
                    if (!IFCAnyHandleUtil.IsNullOrHasNoValue(advancedBRep))
                    {
                        bodyItems.Add(advancedBRep);
                        useFallbackBREP = false; // no need to do Brep since it is successful
                    }
                }

                if (useFallbackBREP)
                {
                    ExporterIFCUtils.CollectGeometryInfo(exporterIFC, info, geomElem, XYZ.Zero, false);
                    HashSet <IFCAnyHandle> faces = new HashSet <IFCAnyHandle>(info.GetSurfaces());
                    IFCAnyHandle           outer = IFCInstanceExporter.CreateClosedShell(file, faces);

                    if (!IFCAnyHandleUtil.IsNullOrHasNoValue(outer))
                    {
                        bodyItems.Add(RepresentationUtil.CreateFacetedBRep(exporterIFC, document,
                                                                           false, outer, ElementId.InvalidElementId));
                    }
                }
            }

            if (bodyItems.Count == 0)
            {
                return(prodDefRep);
            }

            ElementId    catId = CategoryUtil.GetSafeCategoryId(wallElement);
            IFCAnyHandle shapeRep;

            // Use tessellated geometry in Reference View
            if ((ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView || ExporterCacheManager.ExportOptionsCache.ExportAs4General) && !useFallbackBREP)
            {
                shapeRep = RepresentationUtil.CreateTessellatedRep(exporterIFC, wallElement, catId, contextOfItems, bodyItems, null);
            }
            else if (ExporterCacheManager.ExportOptionsCache.ExportAs4DesignTransferView && !useFallbackBREP)
            {
                shapeRep = RepresentationUtil.CreateAdvancedBRepRep(exporterIFC, wallElement, catId, contextOfItems, bodyItems, null);
            }
            else
            {
                shapeRep = RepresentationUtil.CreateBRepRep(exporterIFC, wallElement, catId, contextOfItems, bodyItems);
            }

            if (IFCAnyHandleUtil.IsNullOrHasNoValue(shapeRep))
            {
                return(prodDefRep);
            }

            IList <IFCAnyHandle> shapeReps = new List <IFCAnyHandle>();

            shapeReps.Add(shapeRep);

            IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, wallElement.get_Geometry(geomOptions), Transform.Identity);

            if (boundingBoxRep != null)
            {
                shapeReps.Add(boundingBoxRep);
            }

            prodDefRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps);
            return(prodDefRep);
        }
Пример #46
0
        /// <summary>
        /// Export the individual part (IfcBuildingElementPart).
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="partElement">The part element to export.</param>
        /// <param name="geometryElement">The geometry of part.</param>
        /// <param name="productWrapper">The ProductWrapper object.</param>
        /// <param name="placementSetter"></param>
        /// <param name="originalPlacement"></param>
        /// <param name="range"></param>
        /// <param name="ifcExtrusionAxes"></param>
        /// <param name="hostElement">The host of the part.  This can be null.</param>
        /// <param name="overrideLevelId">The id of the level that the part is one, overridding other sources.</param>
        /// <param name="asBuildingElement">If true, export the Part as a building element instead of an IfcElementPart.</param>
        public static void ExportPart(ExporterIFC exporterIFC, Element partElement, ProductWrapper productWrapper,
                                      PlacementSetter placementSetter, IFCAnyHandle originalPlacement, IFCRange range, IFCExtrusionAxes ifcExtrusionAxes,
                                      Element hostElement, ElementId overrideLevelId, bool asBuildingElement)
        {
            if (!ElementFilteringUtil.IsElementVisible(partElement))
            {
                return;
            }

            Part part = partElement as Part;

            if (part == null)
            {
                return;
            }

            // We don't know how to export a part as a building element if we don't know it's host.
            if (asBuildingElement && (hostElement == null))
            {
                return;
            }

            if (!asBuildingElement)
            {
                // Check the intended IFC entity or type name is in the exclude list specified in the UI
                Common.Enums.IFCEntityType elementClassTypeEnum = Common.Enums.IFCEntityType.IfcBuildingElementPart;
                if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum))
                {
                    return;
                }
            }
            else
            {
                string            ifcEnumType = null;
                IFCExportInfoPair exportType  = ExporterUtil.GetExportType(exporterIFC, hostElement, out ifcEnumType);

                // Check the intended IFC entity or type name is in the exclude list specified in the UI
                Common.Enums.IFCEntityType elementClassTypeEnum;
                if (Enum.TryParse <Common.Enums.IFCEntityType>(exportType.ToString(), out elementClassTypeEnum))
                {
                    if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum))
                    {
                        return;
                    }
                }
            }

            PlacementSetter standalonePlacementSetter = null;
            bool            standaloneExport          = hostElement == null || asBuildingElement;

            ElementId partExportLevelId = (overrideLevelId != null) ? overrideLevelId : null;

            if (partExportLevelId == null && standaloneExport)
            {
                partExportLevelId = partElement.LevelId;
            }

            if (partExportLevelId == null)
            {
                if (hostElement == null || (part.OriginalCategoryId != hostElement.Category.Id))
                {
                    return;
                }
                partExportLevelId = hostElement.LevelId;
            }

            if (ExporterCacheManager.PartExportedCache.HasExported(partElement.Id, partExportLevelId))
            {
                return;
            }

            Options options   = GeometryUtil.GetIFCExportGeometryOptions();
            View    ownerView = partElement.Document.GetElement(partElement.OwnerViewId) as View;

            if (ownerView != null)
            {
                options.View = ownerView;
            }

            GeometryElement geometryElement = partElement.get_Geometry(options);

            if (geometryElement == null)
            {
                return;
            }

            try
            {
                IFCFile file = exporterIFC.GetFile();
                using (IFCTransaction transaction = new IFCTransaction(file))
                {
                    IFCAnyHandle partPlacement = null;
                    if (standaloneExport)
                    {
                        Transform orientationTrf = Transform.Identity;
                        standalonePlacementSetter = PlacementSetter.Create(exporterIFC, partElement, null, orientationTrf, partExportLevelId);
                        partPlacement             = standalonePlacementSetter.LocalPlacement;
                    }
                    else
                    {
                        partPlacement = ExporterUtil.CreateLocalPlacement(file, originalPlacement, null);
                    }

                    bool validRange = (range != null && !MathUtil.IsAlmostZero(range.Start - range.End));

                    SolidMeshGeometryInfo solidMeshInfo;
                    if (validRange)
                    {
                        solidMeshInfo = GeometryUtil.GetSplitClippedSolidMeshGeometry(geometryElement, range);
                        if (solidMeshInfo.GetSolids().Count == 0 && solidMeshInfo.GetMeshes().Count == 0)
                        {
                            return;
                        }
                    }
                    else
                    {
                        solidMeshInfo = GeometryUtil.GetSplitSolidMeshGeometry(geometryElement);
                    }

                    using (IFCExtrusionCreationData extrusionCreationData = new IFCExtrusionCreationData())
                    {
                        extrusionCreationData.SetLocalPlacement(partPlacement);
                        extrusionCreationData.ReuseLocalPlacement   = false;
                        extrusionCreationData.PossibleExtrusionAxes = ifcExtrusionAxes;

                        IList <Solid> solids = solidMeshInfo.GetSolids();
                        IList <Mesh>  meshes = solidMeshInfo.GetMeshes();

                        ElementId catId     = CategoryUtil.GetSafeCategoryId(partElement);
                        ElementId hostCatId = CategoryUtil.GetSafeCategoryId(hostElement);

                        BodyData            bodyData            = null;
                        BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow);
                        if (solids.Count > 0 || meshes.Count > 0)
                        {
                            bodyData = BodyExporter.ExportBody(exporterIFC, partElement, catId, ElementId.InvalidElementId, solids, meshes,
                                                               bodyExporterOptions, extrusionCreationData);
                        }
                        else
                        {
                            IList <GeometryObject> geomlist = new List <GeometryObject>();
                            geomlist.Add(geometryElement);
                            bodyData = BodyExporter.ExportBody(exporterIFC, partElement, catId, ElementId.InvalidElementId, geomlist,
                                                               bodyExporterOptions, extrusionCreationData);
                        }

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

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

                        IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, geometryElement, Transform.Identity);
                        if (boundingBoxRep != null)
                        {
                            representations.Add(boundingBoxRep);
                        }

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

                        IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle;

                        string partGUID = GUIDUtil.CreateGUID(partElement);

                        IFCAnyHandle ifcPart = null;
                        if (!asBuildingElement)
                        {
                            ifcPart = IFCInstanceExporter.CreateBuildingElementPart(exporterIFC, partElement, partGUID, ownerHistory,
                                                                                    extrusionCreationData.GetLocalPlacement(), prodRep);
                        }
                        else
                        {
                            string            ifcEnumType = null;
                            IFCExportInfoPair exportType  = ExporterUtil.GetExportType(exporterIFC, hostElement, out ifcEnumType);

                            switch (exportType.ExportInstance)
                            {
                            case IFCEntityType.IfcColumn:
                                ifcPart = IFCInstanceExporter.CreateColumn(exporterIFC, partElement, partGUID, ownerHistory,
                                                                           extrusionCreationData.GetLocalPlacement(), prodRep, ifcEnumType);
                                break;

                            case IFCEntityType.IfcCovering:
                                ifcPart = IFCInstanceExporter.CreateCovering(exporterIFC, partElement, partGUID, ownerHistory,
                                                                             extrusionCreationData.GetLocalPlacement(), prodRep, ifcEnumType);
                                break;

                            case IFCEntityType.IfcFooting:
                                ifcPart = IFCInstanceExporter.CreateFooting(exporterIFC, partElement, partGUID, ownerHistory,
                                                                            extrusionCreationData.GetLocalPlacement(), prodRep, ifcEnumType);
                                break;

                            case IFCEntityType.IfcPile:
                                ifcPart = IFCInstanceExporter.CreatePile(exporterIFC, partElement, partGUID, ownerHistory,
                                                                         extrusionCreationData.GetLocalPlacement(), prodRep, ifcEnumType, null);
                                break;

                            case IFCEntityType.IfcRoof:
                                ifcPart = IFCInstanceExporter.CreateRoof(exporterIFC, partElement, partGUID, ownerHistory,
                                                                         extrusionCreationData.GetLocalPlacement(), prodRep, ifcEnumType);
                                break;

                            case IFCEntityType.IfcSlab:
                            {
                                // TODO: fix this elsewhere.
                                if (ExporterUtil.IsNotDefined(ifcEnumType))
                                {
                                    if (hostCatId == new ElementId(BuiltInCategory.OST_Floors))
                                    {
                                        ifcEnumType = "FLOOR";
                                    }
                                    else if (hostCatId == new ElementId(BuiltInCategory.OST_Roofs))
                                    {
                                        ifcEnumType = "ROOF";
                                    }
                                }

                                ifcPart = IFCInstanceExporter.CreateSlab(exporterIFC, partElement, partGUID, ownerHistory,
                                                                         extrusionCreationData.GetLocalPlacement(), prodRep, ifcEnumType);
                            }
                            break;

                            case IFCEntityType.IfcWall:
                                ifcPart = IFCInstanceExporter.CreateWall(exporterIFC, partElement, partGUID, ownerHistory,
                                                                         extrusionCreationData.GetLocalPlacement(), prodRep, ifcEnumType);
                                break;

                            default:
                                ifcPart = IFCInstanceExporter.CreateBuildingElementProxy(exporterIFC, partElement, partGUID, ownerHistory,
                                                                                         extrusionCreationData.GetLocalPlacement(), prodRep, null);
                                break;
                            }
                        }

                        bool            containedInLevel     = standaloneExport;
                        PlacementSetter whichPlacementSetter = containedInLevel ? standalonePlacementSetter : placementSetter;
                        productWrapper.AddElement(partElement, ifcPart, whichPlacementSetter, extrusionCreationData, containedInLevel);

                        OpeningUtil.CreateOpeningsIfNecessary(ifcPart, partElement, extrusionCreationData, bodyData.OffsetTransform, exporterIFC,
                                                              extrusionCreationData.GetLocalPlacement(), whichPlacementSetter, productWrapper);

                        //Add the exported part to exported cache.
                        TraceExportedParts(partElement, partExportLevelId, standaloneExport ? ElementId.InvalidElementId : hostElement.Id);

                        CategoryUtil.CreateMaterialAssociation(exporterIFC, ifcPart, bodyData.MaterialIds);

                        transaction.Commit();
                    }
                }
            }
            finally
            {
                if (standalonePlacementSetter != null)
                {
                    standalonePlacementSetter.Dispose();
                }
            }
        }
Пример #47
0
        /// <summary>
        /// Exports a MEP family instance.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="element">The element.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="exportType">The export type of the element.
        /// <param name="ifcEnumType">The sub-type of the element.</param></param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        /// <returns>True if an entity was created, false otherwise.</returns>
        public static bool Export(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement,
                                  IFCExportInfoPair exportType, string ifcEnumType, ProductWrapper productWrapper)
        {
            IFCFile file = exporterIFC.GetFile();

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                // CQ_TODO: Clean up this code by at least factoring it out.

                // If we are exporting a duct segment, we may need to split it into parts by level. Create a list of ranges.
                IList <ElementId> levels = new List <ElementId>();
                IList <IFCRange>  ranges = new List <IFCRange>();

                // We will not split duct segments if the assemblyId is set, as we would like to keep the original duct segment
                // associated with the assembly, on the level of the assembly.
                if ((exportType.ExportType == IFCEntityType.IfcDuctSegmentType) &&
                    (ExporterCacheManager.ExportOptionsCache.WallAndColumnSplitting) &&
                    (element.AssemblyInstanceId == ElementId.InvalidElementId))
                {
                    LevelUtil.CreateSplitLevelRangesForElement(exporterIFC, exportType, element, out levels,
                                                               out ranges);
                }

                int numPartsToExport = ranges.Count;
                {
                    ElementId catId = CategoryUtil.GetSafeCategoryId(element);

                    BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow);
                    if (0 == numPartsToExport)
                    {
                        // 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))
                        {
                            IFCAnyHandle localPlacementToUse = setter.LocalPlacement;
                            BodyData     bodyData            = null;
                            using (IFCExtrusionCreationData extraParams = new IFCExtrusionCreationData())
                            {
                                extraParams.SetLocalPlacement(localPlacementToUse);
                                IFCAnyHandle productRepresentation =
                                    RepresentationUtil.CreateAppropriateProductDefinitionShape(
                                        exporterIFC, element, catId, geometryElement, bodyExporterOptions, null, extraParams, out bodyData);
                                if (IFCAnyHandleUtil.IsNullOrHasNoValue(productRepresentation))
                                {
                                    extraParams.ClearOpenings();
                                    return(false);
                                }

                                ExportAsMappedItem(exporterIFC, element, file, exportType, ifcEnumType, extraParams,
                                                   setter, localPlacementToUse, productRepresentation,
                                                   productWrapper);
                            }
                        }
                    }
                    else
                    {
                        for (int ii = 0; ii < numPartsToExport; ii++)
                        {
                            // Check for containment override
                            IFCAnyHandle overrideContainerHnd = null;
                            ParameterUtil.OverrideContainmentParameter(exporterIFC, element, out overrideContainerHnd);

                            using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element, null, null, levels[ii], overrideContainerHnd))
                            {
                                IFCAnyHandle localPlacementToUse = setter.LocalPlacement;

                                using (IFCExtrusionCreationData extraParams = new IFCExtrusionCreationData())
                                {
                                    SolidMeshGeometryInfo solidMeshCapsule =
                                        GeometryUtil.GetClippedSolidMeshGeometry(geometryElement, ranges[ii]);

                                    IList <Solid> solids     = solidMeshCapsule.GetSolids();
                                    IList <Mesh>  polyMeshes = solidMeshCapsule.GetMeshes();

                                    IList <GeometryObject> geomObjects =
                                        FamilyExporterUtil.RemoveInvisibleSolidsAndMeshes(element.Document,
                                                                                          exporterIFC, ref solids, ref polyMeshes);

                                    if (geomObjects.Count == 0 && (solids.Count > 0 || polyMeshes.Count > 0))
                                    {
                                        return(false);
                                    }

                                    bool tryToExportAsExtrusion = (!exporterIFC.ExportAs2x2 ||
                                                                   (exportType.ExportInstance == IFCEntityType.IfcColumn));

                                    if (exportType.ExportInstance == IFCEntityType.IfcColumn)
                                    {
                                        extraParams.PossibleExtrusionAxes = IFCExtrusionAxes.TryZ;
                                    }
                                    else
                                    {
                                        extraParams.PossibleExtrusionAxes = IFCExtrusionAxes.TryXYZ;
                                    }

                                    BodyData bodyData = null;
                                    if (geomObjects.Count > 0)
                                    {
                                        bodyData = BodyExporter.ExportBody(exporterIFC, element, catId,
                                                                           ElementId.InvalidElementId, geomObjects,
                                                                           bodyExporterOptions, extraParams);
                                    }
                                    else
                                    {
                                        IList <GeometryObject> exportedGeometries = new List <GeometryObject>();
                                        exportedGeometries.Add(geometryElement);
                                        bodyData = BodyExporter.ExportBody(exporterIFC, element, catId,
                                                                           ElementId.InvalidElementId,
                                                                           exportedGeometries, bodyExporterOptions,
                                                                           extraParams);
                                    }

                                    List <IFCAnyHandle> bodyReps = new List <IFCAnyHandle>();
                                    bodyReps.Add(bodyData.RepresentationHnd);

                                    IFCAnyHandle productRepresentation =
                                        IFCInstanceExporter.CreateProductDefinitionShape(exporterIFC.GetFile(), null,
                                                                                         null, bodyReps);
                                    if (IFCAnyHandleUtil.IsNullOrHasNoValue(productRepresentation))
                                    {
                                        extraParams.ClearOpenings();
                                        return(false);
                                    }

                                    ExportAsMappedItem(exporterIFC, element, file, exportType, ifcEnumType,
                                                       extraParams, setter, localPlacementToUse,
                                                       productRepresentation, productWrapper);
                                }
                            }
                        }
                    }
                }

                tr.Commit();
            }
            return(true);
        }
Пример #48
0
        /// <summary>
        /// Exports a MEP family instance.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="element">The element.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="exportType">The export type of the element.
        /// <param name="ifcEnumType">The sub-type of the element.</param></param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        /// <returns>True if an entity was created, false otherwise.</returns>
        public static bool Export(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, 
            IFCExportType exportType, string ifcEnumType, ProductWrapper productWrapper)
        {
            IFCFile file = exporterIFC.GetFile();
            using (IFCTransaction tr = new IFCTransaction(file))
            {
                using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element))
                {
                    IFCAnyHandle localPlacementToUse = setter.LocalPlacement;
                    using (IFCExtrusionCreationData extraParams = new IFCExtrusionCreationData())
                    {
                        extraParams.SetLocalPlacement(localPlacementToUse);

                        ElementId catId = CategoryUtil.GetSafeCategoryId(element);

                        BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true);
                        BodyData bodyData = null;
                        IFCAnyHandle productRepresentation = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC,
                            element, catId, geometryElement, bodyExporterOptions, null, extraParams, out bodyData);
                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(productRepresentation))
                        {
                            extraParams.ClearOpenings();
                            return false;
                        }

                        IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle();
                        ElementId typeId = element.GetTypeId();
                        ElementType type = element.Document.GetElement(typeId) as ElementType;
                        FamilyTypeInfo currentTypeInfo = ExporterCacheManager.TypeObjectsCache.Find(typeId, false);

                        bool found = currentTypeInfo.IsValid();
                        if (!found)
                        {
                            string typeGUID = GUIDUtil.CreateGUID(type);
                            string typeName = NamingUtil.GetNameOverride(type, NamingUtil.GetIFCName(type));
                            string typeObjectType = NamingUtil.GetObjectTypeOverride(type, NamingUtil.CreateIFCObjectName(exporterIFC, type));
                            string applicableOccurence = NamingUtil.GetOverrideStringValue(type, "IfcApplicableOccurrence", typeObjectType);
                            string typeDescription = NamingUtil.GetDescriptionOverride(type, null);
                            string typeTag = NamingUtil.GetTagOverride(type, NamingUtil.CreateIFCElementId(type));
                            string typeElementType = NamingUtil.GetOverrideStringValue(type, "IfcElementType", typeName);

                            IList<IFCAnyHandle> repMapListOpt = new List<IFCAnyHandle>();

                            IFCAnyHandle styleHandle = FamilyExporterUtil.ExportGenericType(exporterIFC, exportType, ifcEnumType, typeGUID, typeName,
                               typeDescription, applicableOccurence, null, repMapListOpt, typeTag, typeElementType, element, type);
                            if (!IFCAnyHandleUtil.IsNullOrHasNoValue(styleHandle))
                            {
                                productWrapper.RegisterHandleWithElementType(type, styleHandle, null);

                                currentTypeInfo.Style = styleHandle;
                                ExporterCacheManager.TypeObjectsCache.Register(typeId, false, currentTypeInfo);
                            }
                        }
                        string instanceGUID = GUIDUtil.CreateGUID(element);
                        string instanceName = NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element));
                        string instanceObjectType = NamingUtil.GetObjectTypeOverride(element, NamingUtil.CreateIFCObjectName(exporterIFC, element));
                        string instanceDescription = NamingUtil.GetDescriptionOverride(element, null);
                        string instanceTag = NamingUtil.GetTagOverride(element, NamingUtil.CreateIFCElementId(element));

                        bool roomRelated = !FamilyExporterUtil.IsDistributionFlowElementSubType(exportType);

                        ElementId roomId = ElementId.InvalidElementId;
                        if (roomRelated)
                        {
                            roomId = setter.UpdateRoomRelativeCoordinates(element, out localPlacementToUse);
                        }

                        IFCAnyHandle instanceHandle = null;

                        // For MEP objects
                        string exportEntityStr = exportType.ToString();
                        Common.Enums.IFCEntityType exportEntity;

                        if (String.Compare(exportEntityStr.Substring(exportEntityStr.Length - 4), "Type", true) == 0)
                            exportEntityStr = exportEntityStr.Substring(0, (exportEntityStr.Length - 4));
                        if (Enum.TryParse(exportEntityStr, out exportEntity))
                        {
                            // For MEP object creation
                            instanceHandle = IFCInstanceExporter.CreateGenericIFCEntity(exportEntity, file, instanceGUID, ownerHistory,
                               instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceTag);
                        }


                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(instanceHandle))
                            return false;

                        bool relatedToSpace = (roomId != ElementId.InvalidElementId);
                        productWrapper.AddElement(element, instanceHandle, setter, extraParams, !relatedToSpace);
                        if (relatedToSpace)
                            ExporterCacheManager.SpaceInfoCache.RelateToSpace(roomId, instanceHandle);

                        OpeningUtil.CreateOpeningsIfNecessary(instanceHandle, element, extraParams, null,
                            exporterIFC, localPlacementToUse, setter, productWrapper);

                        if (currentTypeInfo.IsValid())
                            ExporterCacheManager.TypeRelationsCache.Add(currentTypeInfo.Style, instanceHandle);

                        if (bodyData != null && bodyData.MaterialIds.Count != 0)
                            CategoryUtil.CreateMaterialAssociations(exporterIFC, instanceHandle, bodyData.MaterialIds);

                        ExporterCacheManager.MEPCache.Register(element, instanceHandle);

                        tr.Commit();
                    }
                }
            }
            return true;
        }
        /// <summary>
        /// Creates a SweptSolid, Brep, SolidModel or SurfaceModel product definition shape representation, based on the geometry and IFC version.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="categoryId">The category id.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="bodyExporterOptions">The body exporter options.</param>
        /// <param name="extraReps">Extra representations (e.g. Axis, Boundary).  May be null.</param>
        /// <param name="extrusionCreationData">The extrusion creation data.</param>
        /// <param name="bodyData">The body data.</param>
        /// <returns>The handle.</returns>
        public static IFCAnyHandle CreateAppropriateProductDefinitionShape(ExporterIFC exporterIFC, Element element, ElementId categoryId,
            GeometryElement geometryElement, BodyExporterOptions bodyExporterOptions, IList<IFCAnyHandle> extraReps,
            IFCExtrusionCreationData extrusionCreationData, out BodyData bodyData)
        {
            bodyData = null;
            SolidMeshGeometryInfo info = null;
            IList<GeometryObject> geometryList = new List<GeometryObject>();

            if (!ExporterCacheManager.ExportOptionsCache.ExportAs2x2)
            {
                info = GeometryUtil.GetSplitSolidMeshGeometry(geometryElement, Transform.Identity);
                IList<Mesh> meshes = info.GetMeshes();
                if (meshes.Count == 0)
                {
                    IList<Solid> solidList = info.GetSolids();
                    foreach (Solid solid in solidList)
                    {
                        geometryList.Add(solid);
                    }
                }
            }

            if (geometryList.Count == 0)
                geometryList.Add(geometryElement);
            else
                bodyExporterOptions.TryToExportAsExtrusion = true;

            bodyData = BodyExporter.ExportBody(exporterIFC, element, categoryId, ElementId.InvalidElementId, geometryList,
                bodyExporterOptions, extrusionCreationData);
            IFCAnyHandle bodyRep = bodyData.RepresentationHnd;
            List<IFCAnyHandle> bodyReps = new List<IFCAnyHandle>();
            if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep))
            {
                if (extrusionCreationData != null)
                    extrusionCreationData.ClearOpenings();
            }
            else
                bodyReps.Add(bodyRep);

            if (extraReps != null)
            {
                foreach (IFCAnyHandle hnd in extraReps)
                    bodyReps.Add(hnd);
            }

            Transform boundingBoxTrf = (bodyData.OffsetTransform != null) ? bodyData.OffsetTransform.Inverse : Transform.Identity;
            IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, geometryElement, boundingBoxTrf);
            if (boundingBoxRep != null)
                bodyReps.Add(boundingBoxRep);

            if (bodyReps.Count == 0)
                return null;
            return IFCInstanceExporter.CreateProductDefinitionShape(exporterIFC.GetFile(), null, null, bodyReps);
        }
Пример #50
0
        /// <summary>
        /// Exports a MEP family instance.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="element">The element.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="exportType">The export type of the element.
        /// <param name="ifcEnumType">The sub-type of the element.</param></param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        /// <returns>True if an entity was created, false otherwise.</returns>
        public static bool Export(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement,
                                  IFCExportType exportType, string ifcEnumType, ProductWrapper productWrapper)
        {
            IFCFile file = exporterIFC.GetFile();

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element))
                {
                    IFCAnyHandle localPlacementToUse = setter.LocalPlacement;
                    using (IFCExtrusionCreationData extraParams = new IFCExtrusionCreationData())
                    {
                        extraParams.SetLocalPlacement(localPlacementToUse);

                        ElementId catId = CategoryUtil.GetSafeCategoryId(element);

                        BodyExporterOptions bodyExporterOptions   = new BodyExporterOptions(true);
                        BodyData            bodyData              = null;
                        IFCAnyHandle        productRepresentation = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC,
                                                                                                                               element, catId, geometryElement, bodyExporterOptions, null, extraParams, out bodyData);
                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(productRepresentation))
                        {
                            extraParams.ClearOpenings();
                            return(false);
                        }

                        IFCAnyHandle   ownerHistory    = exporterIFC.GetOwnerHistoryHandle();
                        ElementId      typeId          = element.GetTypeId();
                        ElementType    type            = element.Document.GetElement(typeId) as ElementType;
                        FamilyTypeInfo currentTypeInfo = ExporterCacheManager.TypeObjectsCache.Find(typeId, false);

                        bool found = currentTypeInfo.IsValid();
                        if (!found)
                        {
                            string typeGUID            = GUIDUtil.CreateGUID(type);
                            string typeName            = NamingUtil.GetNameOverride(type, NamingUtil.GetIFCName(type));
                            string typeObjectType      = NamingUtil.GetObjectTypeOverride(type, NamingUtil.CreateIFCObjectName(exporterIFC, type));
                            string applicableOccurence = NamingUtil.GetOverrideStringValue(type, "IfcApplicableOccurrence", typeObjectType);
                            string typeDescription     = NamingUtil.GetDescriptionOverride(type, null);
                            string typeTag             = NamingUtil.GetTagOverride(type, NamingUtil.CreateIFCElementId(type));
                            string typeElementType     = NamingUtil.GetOverrideStringValue(type, "IfcElementType", typeName);

                            IList <IFCAnyHandle> repMapListOpt = new List <IFCAnyHandle>();

                            IFCAnyHandle styleHandle = FamilyExporterUtil.ExportGenericType(exporterIFC, exportType, ifcEnumType, typeGUID, typeName,
                                                                                            typeDescription, applicableOccurence, null, repMapListOpt, typeTag, typeElementType, element, type);
                            if (!IFCAnyHandleUtil.IsNullOrHasNoValue(styleHandle))
                            {
                                productWrapper.RegisterHandleWithElementType(type, styleHandle, null);

                                currentTypeInfo.Style = styleHandle;
                                ExporterCacheManager.TypeObjectsCache.Register(typeId, false, currentTypeInfo);
                            }
                        }
                        string instanceGUID        = GUIDUtil.CreateGUID(element);
                        string instanceName        = NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element));
                        string instanceObjectType  = NamingUtil.GetObjectTypeOverride(element, NamingUtil.CreateIFCObjectName(exporterIFC, element));
                        string instanceDescription = NamingUtil.GetDescriptionOverride(element, null);
                        string instanceTag         = NamingUtil.GetTagOverride(element, NamingUtil.CreateIFCElementId(element));

                        bool roomRelated = !FamilyExporterUtil.IsDistributionFlowElementSubType(exportType);

                        ElementId roomId = ElementId.InvalidElementId;
                        if (roomRelated)
                        {
                            roomId = setter.UpdateRoomRelativeCoordinates(element, out localPlacementToUse);
                        }

                        IFCAnyHandle instanceHandle = null;

                        // For MEP objects
                        string exportEntityStr = exportType.ToString();
                        Common.Enums.IFCEntityType exportEntity;

                        if (String.Compare(exportEntityStr.Substring(exportEntityStr.Length - 4), "Type", true) == 0)
                        {
                            exportEntityStr = exportEntityStr.Substring(0, (exportEntityStr.Length - 4));
                        }
                        if (Enum.TryParse(exportEntityStr, out exportEntity))
                        {
                            // For MEP object creation
                            instanceHandle = IFCInstanceExporter.CreateGenericIFCEntity(exportEntity, file, instanceGUID, ownerHistory,
                                                                                        instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceTag);
                        }


                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(instanceHandle))
                        {
                            return(false);
                        }

                        bool relatedToSpace = (roomId != ElementId.InvalidElementId);
                        productWrapper.AddElement(element, instanceHandle, setter, extraParams, !relatedToSpace);
                        if (relatedToSpace)
                        {
                            ExporterCacheManager.SpaceInfoCache.RelateToSpace(roomId, instanceHandle);
                        }

                        OpeningUtil.CreateOpeningsIfNecessary(instanceHandle, element, extraParams, null,
                                                              exporterIFC, localPlacementToUse, setter, productWrapper);

                        if (currentTypeInfo.IsValid())
                        {
                            ExporterCacheManager.TypeRelationsCache.Add(currentTypeInfo.Style, instanceHandle);
                        }

                        if (bodyData != null && bodyData.MaterialIds.Count != 0)
                        {
                            CategoryUtil.CreateMaterialAssociations(exporterIFC, instanceHandle, bodyData.MaterialIds);
                        }

                        ExporterCacheManager.MEPCache.Register(element, instanceHandle);

                        tr.Commit();
                    }
                }
            }
            return(true);
        }
Пример #51
0
        /// <summary>
        /// Creates an opening from a solid.
        /// </summary>
        /// <param name="exporterIFC">The exporter.</param>
        /// <param name="hostObjHnd">The host object handle.</param>
        /// <param name="hostElement">The host element.</param>
        /// <param name="insertElement">The insert element.</param>
        /// <param name="openingGUID">The GUID for the opening, depending on how the opening is created.</param>
        /// <param name="solid">The solid.</param>
        /// <param name="scaledHostWidth">The scaled host width.</param>
        /// <param name="isRecess">True if it is recess.</param>
        /// <param name="extrusionCreationData">The extrusion creation data.</param>
        /// <param name="setter">The placement setter.</param>
        /// <param name="localWrapper">The product wrapper.</param>
        /// <returns>The created opening handle.</returns>
        static public IFCAnyHandle CreateOpening(ExporterIFC exporterIFC, IFCAnyHandle hostObjHnd, Element hostElement, Element insertElement, string openingGUID,
            Solid solid, double scaledHostWidth, bool isRecess, IFCExtrusionCreationData extrusionCreationData, PlacementSetter setter, ProductWrapper localWrapper)
        {
            IFCFile file = exporterIFC.GetFile();

            ElementId catId = CategoryUtil.GetSafeCategoryId(insertElement);

            XYZ prepToWall;
            bool isLinearWall = GetOpeningDirection(hostElement, out prepToWall);
            if (isLinearWall)
            {
                extrusionCreationData.CustomAxis = prepToWall;
                extrusionCreationData.PossibleExtrusionAxes = IFCExtrusionAxes.TryCustom;
            }

            BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true);
            BodyData bodyData = BodyExporter.ExportBody(exporterIFC, insertElement, catId, ElementId.InvalidElementId,
                solid, bodyExporterOptions, extrusionCreationData);

            IFCAnyHandle openingRepHnd = bodyData.RepresentationHnd;
            if (IFCAnyHandleUtil.IsNullOrHasNoValue(openingRepHnd))
            {
                extrusionCreationData.ClearOpenings();
                return null;
            }
            IList<IFCAnyHandle> representations = new List<IFCAnyHandle>();
            representations.Add(openingRepHnd);
            IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, representations);

            IFCAnyHandle openingPlacement = extrusionCreationData.GetLocalPlacement();
            IFCAnyHandle hostObjPlacementHnd = IFCAnyHandleUtil.GetObjectPlacement(hostObjHnd);
            Transform relTransform = ExporterIFCUtils.GetRelativeLocalPlacementOffsetTransform(openingPlacement, hostObjPlacementHnd);

            openingPlacement = ExporterUtil.CreateLocalPlacement(file, hostObjPlacementHnd,
                relTransform.Origin, relTransform.BasisZ, relTransform.BasisX);

            IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle();
            double scaledOpeningLength = extrusionCreationData.ScaledLength;
            string openingObjectType = "Opening";
            if (!MathUtil.IsAlmostZero(scaledHostWidth) && !MathUtil.IsAlmostZero(scaledOpeningLength))
                 openingObjectType = scaledOpeningLength < (scaledHostWidth - MathUtil.Eps()) ? "Recess" : "Opening";
            else
                openingObjectType = isRecess ? "Recess" : "Opening";
            
            string openingName = NamingUtil.GetNameOverride(insertElement, null);
            if (string.IsNullOrEmpty(openingName))
            {
                if (!IFCAnyHandleUtil.IsNullOrHasNoValue(hostObjHnd))
                    openingName = IFCAnyHandleUtil.GetStringAttribute(hostObjHnd, "Name");
                else
                    openingName = NamingUtil.GetNameOverride(hostElement, NamingUtil.CreateIFCObjectName(exporterIFC, hostElement));
            }
            
            IFCAnyHandle openingHnd = IFCInstanceExporter.CreateOpeningElement(file, openingGUID, ownerHistory, openingName, null,
                openingObjectType, openingPlacement, prodRep, null);
            if (ExporterCacheManager.ExportOptionsCache.ExportBaseQuantities)
                PropertyUtil.CreateOpeningQuantities(exporterIFC, openingHnd, extrusionCreationData);

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

                localWrapper.AddElement(insertElement, openingHnd, setter, extrusionCreationData, true);
            }

            string voidGuid = GUIDUtil.CreateGUID();
            IFCInstanceExporter.CreateRelVoidsElement(file, voidGuid, ownerHistory, null, null, hostObjHnd, openingHnd);
            return openingHnd;
        }
Пример #52
0
        /// <summary>
        /// Exports an element to IfcPile.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="element">The element.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="ifcEnumType">The string value represents the IFC type.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        public static void ExportPile(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement,
                                      string ifcEnumType, ProductWrapper productWrapper)
        {
            // NOTE: We expect to incorporate this code into the generic FamilyInstanceExporter at some point.
            // export parts or not
            bool exportParts = PartExporter.CanExportParts(element);

            if (exportParts && !PartExporter.CanExportElementInPartExport(element, element.LevelId, false))
            {
                return;
            }

            IFCFile file = exporterIFC.GetFile();

            using (IFCTransaction tr = 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())
                    {
                        ecData.SetLocalPlacement(setter.LocalPlacement);

                        IFCAnyHandle prodRep = null;
                        ElementId    matId   = ElementId.InvalidElementId;
                        if (!exportParts)
                        {
                            ElementId catId = CategoryUtil.GetSafeCategoryId(element);


                            matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geometryElement, exporterIFC, element);
                            BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow);

                            StructuralMemberAxisInfo axisInfo = StructuralMemberExporter.GetStructuralMemberAxisTransform(element);
                            if (axisInfo != null)
                            {
                                ecData.CustomAxis            = axisInfo.AxisDirection;
                                ecData.PossibleExtrusionAxes = IFCExtrusionAxes.TryCustom;
                            }
                            else
                            {
                                ecData.PossibleExtrusionAxes = IFCExtrusionAxes.TryZ;
                            }

                            prodRep = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC,
                                                                                                 element, catId, geometryElement, bodyExporterOptions, null, ecData, true);
                            if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodRep))
                            {
                                ecData.ClearOpenings();
                                return;
                            }
                        }

                        string            instanceGUID = GUIDUtil.CreateGUID(element);
                        IFCExportInfoPair exportInfo   = new IFCExportInfoPair(Common.Enums.IFCEntityType.IfcPile, ifcEnumType);

                        IFCAnyHandle pile = IFCInstanceExporter.CreatePile(exporterIFC, element, instanceGUID, ExporterCacheManager.OwnerHistoryHandle,
                                                                           ecData.GetLocalPlacement(), prodRep, ifcEnumType, null);

                        // TODO: to allow shared geometry for Piles. For now, Pile export will not use shared geometry
                        if (exportInfo.ExportType != Common.Enums.IFCEntityType.UnKnown)
                        {
                            IFCAnyHandle type = ExporterUtil.CreateGenericTypeFromElement(element, exportInfo, file, ExporterCacheManager.OwnerHistoryHandle, exportInfo.ValidatedPredefinedType, productWrapper);
                            ExporterCacheManager.TypeRelationsCache.Add(type, pile);
                        }
                        if (exportParts)
                        {
                            PartExporter.ExportHostPart(exporterIFC, element, pile, productWrapper, setter, setter.LocalPlacement, null);
                        }
                        else
                        {
                            if (matId != ElementId.InvalidElementId)
                            {
                                CategoryUtil.CreateMaterialAssociation(exporterIFC, pile, matId);
                            }
                        }

                        productWrapper.AddElement(element, pile, setter, ecData, true, exportInfo);

                        OpeningUtil.CreateOpeningsIfNecessary(pile, element, ecData, null,
                                                              exporterIFC, ecData.GetLocalPlacement(), setter, productWrapper);
                    }
                }

                tr.Commit();
            }
        }
        /// <summary>
        /// Exports mullion.
        /// </summary>
        /// <param name="exporterIFC">
        /// The ExporterIFC object.
        /// </param>
        /// <param name="mullion">
        /// The mullion object.
        /// </param>
        /// <param name="geometryElement">
        /// The geometry element.
        /// </param>
        /// <param name="localPlacement">
        /// The local placement handle.
        /// </param>
        /// <param name="setter">
        /// The PlacementSetter.
        /// </param>
        /// <param name="productWrapper">
        /// The ProductWrapper.
        /// </param>
        public static void Export(ExporterIFC exporterIFC, Mullion mullion, GeometryElement geometryElement,
           IFCAnyHandle localPlacement, PlacementSetter setter, ProductWrapper productWrapper)
        {
            IFCFile file = exporterIFC.GetFile();

            using (PlacementSetter mullionSetter = PlacementSetter.Create(exporterIFC, mullion))
            {
                using (IFCExtrusionCreationData extraParams = new IFCExtrusionCreationData())
                {
                    IFCAnyHandle mullionPlacement = mullionSetter.LocalPlacement;
                    
                    Transform relTrf = ExporterIFCUtils.GetRelativeLocalPlacementOffsetTransform(localPlacement, mullionPlacement);
                    Transform inverseTrf = relTrf.Inverse;

                    IFCAnyHandle mullionLocalPlacement = ExporterUtil.CreateLocalPlacement(file, localPlacement,
                        inverseTrf.Origin, inverseTrf.BasisZ, inverseTrf.BasisX);

                    extraParams.SetLocalPlacement(mullionLocalPlacement);

                    Transform extrusionLCS = null;
                    // Add a custom direction for trying to create an extrusion based on the base curve of the mullion, if it is a line and not an arc.
                    Curve baseCurve = mullion.LocationCurve;
                    if ((baseCurve != null) && (baseCurve is Line))
                    {
                        // We won't use curveBounds and origin yet; just need the axis for now.
                        IFCRange curveBounds;
                        XYZ origin, mullionDirection;
                        GeometryUtil.GetAxisAndRangeFromCurve(baseCurve, out curveBounds, out mullionDirection, out origin);

                        // approx 1.0/sqrt(2.0)
                        XYZ planeY = (Math.Abs(mullionDirection.Z) < 0.707) ? XYZ.BasisZ.CrossProduct(mullionDirection) : XYZ.BasisX.CrossProduct(mullionDirection);
                        planeY.Normalize();

                        XYZ projDir = mullionDirection.CrossProduct(planeY);

                        extrusionLCS = Transform.Identity;
                        extrusionLCS.BasisX = mullionDirection; extrusionLCS.BasisY = planeY; extrusionLCS.BasisZ = projDir; extrusionLCS.Origin = origin;
                    }

                    ElementId catId = CategoryUtil.GetSafeCategoryId(mullion);

                    BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true);
                    bodyExporterOptions.ExtrusionLocalCoordinateSystem = extrusionLCS;

                    IFCAnyHandle repHnd = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, mullion, catId,
                        geometryElement, bodyExporterOptions, null, extraParams, true);
                    if (IFCAnyHandleUtil.IsNullOrHasNoValue(repHnd))
                    {
                        extraParams.ClearOpenings();
                        return;
                    }

                    string elemGUID = GUIDUtil.CreateGUID(mullion);
                    IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle();
                    string elemObjectType = NamingUtil.CreateIFCObjectName(exporterIFC, mullion);
                    string name = NamingUtil.GetNameOverride(mullion, elemObjectType);
                    string description = NamingUtil.GetDescriptionOverride(mullion, null);
                    string objectType = NamingUtil.GetObjectTypeOverride(mullion, elemObjectType);
                    string elemTag = NamingUtil.GetTagOverride(mullion, NamingUtil.CreateIFCElementId(mullion));

                    IFCAnyHandle mullionHnd = IFCInstanceExporter.CreateMember(file, elemGUID, ownerHistory, name, description, objectType,
                       mullionLocalPlacement, repHnd, elemTag, "MULLION");
                    ExporterCacheManager.HandleToElementCache.Register(mullionHnd, mullion.Id);

                    productWrapper.AddElement(mullion, mullionHnd, mullionSetter, extraParams, false);

                    ElementId matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geometryElement, exporterIFC, mullion);
                    CategoryUtil.CreateMaterialAssociation(exporterIFC, mullionHnd, matId);
                }
            }
        }
Пример #54
0
        /// <summary>
        /// Exports a beam to IFC beam if it has an axis representation and only one Solid as its geometry, ideally as an extrusion, potentially with clippings and openings.
        /// </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>
        /// <param name="dontExport">An output value that says that the element shouldn't be exported at all.</param>
        /// <returns>The created handle.</returns>
        /// <remarks>In the original implementation, the ExportBeam function would export each beam as its own individual geometry (that is, not use representation maps).
        /// For non-standard beams, this could result in massive IFC files.  Now, we use the ExportBeamAsStandardElement function and limit its scope, and instead
        /// resort to the standard FamilyInstanceExporter.ExportFamilyInstanceAsMappedItem for more complicated objects categorized as beams.  This has the following pros and cons:
        /// Pro: possiblity for massively reduced file sizes for files containing repeated complex beam families
        /// Con: some beams that may have had an "Axis" representation before will no longer have them, although this possibility is minimized.
        /// Con: some beams that have 1 Solid and an axis, but that Solid will be heavily faceted, won't be helped by this improvement.
        /// It is intended that we phase out this routine entirely and instead teach ExportFamilyInstanceAsMappedItem how to sometimes export the Axis representation for beams.</remarks>
        public static IFCAnyHandle ExportBeamAsStandardElement(ExporterIFC exporterIFC,
                                                               Element element, IFCExportInfoPair exportType, GeometryElement geometryElement, ProductWrapper productWrapper, out bool dontExport)
        {
            dontExport = true;
            IList <GeometryObject> geomObjects = BeamGeometryToExport(exporterIFC, element, geometryElement, out dontExport);

            if (dontExport)
            {
                return(null);
            }

            IFCAnyHandle       beam = null;
            IFCFile            file = exporterIFC.GetFile();
            MaterialAndProfile materialAndProfile = null;
            IFCAnyHandle       materialProfileSet = null;

            using (IFCTransaction transaction = new IFCTransaction(file))
            {
                BeamAxisInfo axisInfo      = GetBeamAxisTransform(element);
                bool         canExportAxis = (axisInfo != null);

                Curve     curve         = canExportAxis ? axisInfo.Axis : null;
                XYZ       beamDirection = canExportAxis ? axisInfo.AxisDirection : null;
                Transform orientTrf     = canExportAxis ? axisInfo.LCSAsTransform : null;

                // Check for containment override
                IFCAnyHandle overrideContainerHnd = null;
                ElementId    overrideContainerId  = ParameterUtil.OverrideContainmentParameter(exporterIFC, element, out overrideContainerHnd);
                using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element, null, orientTrf, overrideContainerId, overrideContainerHnd))
                {
                    IFCAnyHandle localPlacement = setter.LocalPlacement;
                    using (IFCExtrusionCreationData extrusionCreationData = new IFCExtrusionCreationData())
                    {
                        extrusionCreationData.SetLocalPlacement(localPlacement);
                        if (canExportAxis && (orientTrf.BasisX != null))
                        {
                            extrusionCreationData.CustomAxis            = beamDirection;
                            extrusionCreationData.PossibleExtrusionAxes = IFCExtrusionAxes.TryCustom;
                        }
                        else
                        {
                            extrusionCreationData.PossibleExtrusionAxes = IFCExtrusionAxes.TryXY;
                        }

                        ElementId catId = CategoryUtil.GetSafeCategoryId(element);

                        // There may be an offset to make the local coordinate system
                        // be near the origin.  This offset will be used to move the axis to the new LCS.
                        Transform offsetTransform = null;

                        // The list of materials in the solids or meshes.
                        ICollection <ElementId> materialIds = null;

                        // If the beam is a FamilyInstance, and it uses transformed FamilySymbol geometry only, then
                        // let's only try to CreateBeamGeometryAsExtrusion unsuccesfully once.  Otherwise, we can spend a lot of time trying
                        // unsuccessfully to do so.
                        bool tryToCreateBeamGeometryAsExtrusion = true;

                        //bool useFamilySymbolGeometry = (element is FamilyInstance) ? !ExporterIFCUtils.UsesInstanceGeometry(element as FamilyInstance) : false;
                        bool      useFamilySymbolGeometry = (element is FamilyInstance) ? !GeometryUtil.UsesInstanceGeometry(element as FamilyInstance) : false;
                        ElementId beamTypeId = element.GetTypeId();
                        if (useFamilySymbolGeometry)
                        {
                            tryToCreateBeamGeometryAsExtrusion = !ExporterCacheManager.CanExportBeamGeometryAsExtrusionCache.ContainsKey(beamTypeId) ||
                                                                 ExporterCacheManager.CanExportBeamGeometryAsExtrusionCache[beamTypeId];
                        }

                        // The representation handle generated from one of the methods below.
                        BeamBodyAsExtrusionInfo extrusionInfo = null;
                        if (tryToCreateBeamGeometryAsExtrusion)
                        {
                            extrusionInfo = CreateBeamGeometryAsExtrusion(exporterIFC, element, catId, geomObjects, axisInfo);
                            if (useFamilySymbolGeometry)
                            {
                                ExporterCacheManager.CanExportBeamGeometryAsExtrusionCache[beamTypeId] = (extrusionInfo != null);
                            }
                        }

                        if (extrusionInfo != null && extrusionInfo.DontExport)
                        {
                            dontExport = true;
                            return(null);
                        }

                        IFCAnyHandle repHnd = (extrusionInfo != null) ? extrusionInfo.RepresentationHandle : null;

                        if (!IFCAnyHandleUtil.IsNullOrHasNoValue(repHnd))
                        {
                            materialIds = extrusionInfo.Materials;
                            extrusionCreationData.Slope = extrusionInfo.Slope;
                        }
                        else
                        {
                            // Here is where we limit the scope of how complex a case we will still try to export as a standard element.
                            // This is explicitly added so that many curved beams that can be represented by a reasonable facetation because of the
                            // SweptSolidExporter can still have an Axis representation.
                            BodyData bodyData = null;

                            BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow);
                            if (ExporterCacheManager.ExportOptionsCache.ExportAs4ReferenceView)
                            {
                                bodyExporterOptions.CollectMaterialAndProfile = false;
                            }
                            else
                            {
                                bodyExporterOptions.CollectMaterialAndProfile = true;
                            }

                            if (geomObjects != null && geomObjects.Count == 1 && geomObjects[0] is Solid)
                            {
                                bodyData = BodyExporter.ExportBody(exporterIFC, element, catId, ElementId.InvalidElementId,
                                                                   geomObjects[0], bodyExporterOptions, extrusionCreationData);

                                repHnd      = bodyData.RepresentationHnd;
                                materialIds = bodyData.MaterialIds;
                                if (!bodyData.OffsetTransform.IsIdentity)
                                {
                                    offsetTransform = bodyData.OffsetTransform;
                                }
                                materialAndProfile = bodyData.MaterialAndProfile;
                            }
                        }

                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(repHnd))
                        {
                            extrusionCreationData.ClearOpenings();
                            return(null);
                        }

                        IList <IFCAnyHandle> representations = new List <IFCAnyHandle>();
                        IFCAnyHandle         axisRep         = CreateBeamAxis(exporterIFC, element, catId, axisInfo, offsetTransform);
                        if (!IFCAnyHandleUtil.IsNullOrHasNoValue(axisRep))
                        {
                            representations.Add(axisRep);
                        }
                        representations.Add(repHnd);

                        Transform    boundingBoxTrf = (offsetTransform == null) ? Transform.Identity : offsetTransform.Inverse;
                        IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, geometryElement, boundingBoxTrf);
                        if (boundingBoxRep != null)
                        {
                            representations.Add(boundingBoxRep);
                        }

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

                        string instanceGUID = GUIDUtil.CreateGUID(element);
                        beam = IFCInstanceExporter.CreateBeam(exporterIFC, element, instanceGUID, ExporterCacheManager.OwnerHistoryHandle, extrusionCreationData.GetLocalPlacement(), prodRep, exportType.ValidatedPredefinedType);


                        IFCAnyHandle mpSetUsage;
                        if (materialProfileSet != null)
                        {
                            mpSetUsage = IFCInstanceExporter.CreateMaterialProfileSetUsage(file, materialProfileSet, null, null);
                        }

                        productWrapper.AddElement(element, beam, setter, extrusionCreationData, true, exportType);

                        ExportBeamType(exporterIFC, productWrapper, beam, element, exportType.ValidatedPredefinedType);

                        OpeningUtil.CreateOpeningsIfNecessary(beam, element, extrusionCreationData, offsetTransform, exporterIFC,
                                                              extrusionCreationData.GetLocalPlacement(), setter, productWrapper);

                        FamilyTypeInfo typeInfo = new FamilyTypeInfo();
                        typeInfo.ScaledDepth          = extrusionCreationData.ScaledLength;
                        typeInfo.ScaledArea           = extrusionCreationData.ScaledArea;
                        typeInfo.ScaledInnerPerimeter = extrusionCreationData.ScaledInnerPerimeter;
                        typeInfo.ScaledOuterPerimeter = extrusionCreationData.ScaledOuterPerimeter;
                        PropertyUtil.CreateBeamColumnBaseQuantities(exporterIFC, beam, element, typeInfo, null);

                        if (materialIds.Count != 0)
                        {
                            CategoryUtil.CreateMaterialAssociation(exporterIFC, beam, materialIds);
                        }

                        // Register the beam's IFC handle for later use by truss and beam system export.
                        ExporterCacheManager.ElementToHandleCache.Register(element.Id, beam, exportType);
                    }
                }

                transaction.Commit();
                return(beam);
            }
        }
        /// <summary>
        /// Creates IFC room/space/area item, not include boundaries. 
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="spatialElement">The spatial element.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        /// <param name="setter">The PlacementSetter.</param>
        /// <returns>True if created successfully, false otherwise.</returns>
        static bool CreateIFCSpace(ExporterIFC exporterIFC, SpatialElement spatialElement, ProductWrapper productWrapper, 
            PlacementSetter setter, out SpatialElementGeometryResults results)
        {
            results = null;

            IList<CurveLoop> curveLoops = null;
            try
            {
                // Avoid throwing for a spatial element with no location.
                if (spatialElement.Location == null)
                    return false;

                SpatialElementBoundaryOptions options = GetSpatialElementBoundaryOptions(spatialElement);
                curveLoops = ExporterIFCUtils.GetRoomBoundaryAsCurveLoopArray(spatialElement, options, true);
            }
            catch (Autodesk.Revit.Exceptions.InvalidOperationException)
            {
                //Some spatial elements are not placed that have no boundary loops. Don't export them.
                return false;
            }

            Autodesk.Revit.DB.Document document = spatialElement.Document;
            ElementId levelId = spatialElement.LevelId;

            ElementId catId = spatialElement.Category != null ? spatialElement.Category.Id : ElementId.InvalidElementId;

            double dArea = 0.0;
            if (ParameterUtil.GetDoubleValueFromElement(spatialElement, BuiltInParameter.ROOM_AREA, out dArea) != null)
                dArea = UnitUtil.ScaleArea(dArea);

            IFCLevelInfo levelInfo = exporterIFC.GetLevelInfo(levelId);

            string strSpaceNumber = null;
            string strSpaceName = null;
            string strSpaceDesc = null;

            if (ParameterUtil.GetStringValueFromElement(spatialElement, BuiltInParameter.ROOM_NUMBER, out strSpaceNumber) == null)
                strSpaceNumber = null;

            if (ParameterUtil.GetStringValueFromElement(spatialElement, BuiltInParameter.ROOM_NAME, out strSpaceName) == null)
                strSpaceName = null;

            if (ParameterUtil.GetStringValueFromElement(spatialElement, BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS, out strSpaceDesc) == null)
                strSpaceDesc = null;

            string name = strSpaceNumber;
            string longName = strSpaceName;
            string desc = strSpaceDesc;

            IFCFile file = exporterIFC.GetFile();

            IFCAnyHandle localPlacement = setter.LocalPlacement;
            ElementType elemType = document.GetElement(spatialElement.GetTypeId()) as ElementType;
            IFCInternalOrExternal internalOrExternal = CategoryUtil.IsElementExternal(spatialElement) ? IFCInternalOrExternal.External : IFCInternalOrExternal.Internal;

            double scaledRoomHeight = GetScaledHeight(spatialElement, levelId, levelInfo);
            if (scaledRoomHeight <= 0.0)
                return false;

            double bottomOffset;
            ParameterUtil.GetDoubleValueFromElement(spatialElement, BuiltInParameter.ROOM_LOWER_OFFSET, out bottomOffset);

         double elevation = (levelInfo != null) ? levelInfo.Elevation : 0.0;
            XYZ zDir = new XYZ(0, 0, 1);
         XYZ orig = new XYZ(0, 0, elevation + bottomOffset);

            Plane plane = new Plane(zDir, orig); // room calculated as level offset.

            GeometryElement geomElem = null;
            bool isArea = (spatialElement is Area);
            Area spatialElementAsArea = isArea ? (spatialElement as Area) : null;

            if (spatialElement is Autodesk.Revit.DB.Architecture.Room)
            {
                Autodesk.Revit.DB.Architecture.Room room = spatialElement as Autodesk.Revit.DB.Architecture.Room;
                geomElem = room.ClosedShell;
            }
            else if (spatialElement is Autodesk.Revit.DB.Mechanical.Space)
            {
                Autodesk.Revit.DB.Mechanical.Space space = spatialElement as Autodesk.Revit.DB.Mechanical.Space;
                geomElem = space.ClosedShell;
            }
            else if (isArea)
            {
                Options geomOptions = GeometryUtil.GetIFCExportGeometryOptions();
                geomElem = spatialElementAsArea.get_Geometry(geomOptions);
            }

            IFCAnyHandle spaceHnd = null;
            string spatialElementName = null;
            using (IFCExtrusionCreationData extraParams = new IFCExtrusionCreationData())
            {
                extraParams.SetLocalPlacement(localPlacement);
                extraParams.PossibleExtrusionAxes = IFCExtrusionAxes.TryZ;

                using (IFCTransaction transaction2 = new IFCTransaction(file))
                {
                    IFCAnyHandle repHnd = null;
                    if (!ExporterCacheManager.ExportOptionsCache.Use2DRoomBoundaryForRoomVolumeCreation && geomElem != null)
                    {
                        BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true);
                        bodyExporterOptions.TessellationLevel = BodyExporter.GetTessellationLevel();
                        repHnd = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, spatialElement,
                            catId, geomElem, bodyExporterOptions, null, extraParams, false);
                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(repHnd))
                            extraParams.ClearOpenings();
                    }
                    else
                    {
                        IFCAnyHandle shapeRep = ExtrusionExporter.CreateExtrudedSolidFromCurveLoop(exporterIFC, null, curveLoops, plane, zDir, scaledRoomHeight);
                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(shapeRep))
                            return false;
                        IFCAnyHandle styledItemHnd = BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, document,
                            shapeRep, ElementId.InvalidElementId);

                        HashSet<IFCAnyHandle> bodyItems = new HashSet<IFCAnyHandle>();
                        bodyItems.Add(shapeRep);
                        shapeRep = RepresentationUtil.CreateSweptSolidRep(exporterIFC, spatialElement, catId, exporterIFC.Get3DContextHandle("Body"), bodyItems, null);
                        IList<IFCAnyHandle> shapeReps = new List<IFCAnyHandle>();
                        shapeReps.Add(shapeRep);

                        IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, geomElem, Transform.Identity);
                        if (boundingBoxRep != null)
                            shapeReps.Add(boundingBoxRep);

                        repHnd = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps);
                    }

                    extraParams.ScaledHeight = scaledRoomHeight;
                    extraParams.ScaledArea = dArea;

                    spatialElementName = NamingUtil.GetNameOverride(spatialElement, name);
                    string spatialElementDescription = NamingUtil.GetDescriptionOverride(spatialElement, desc);
                    string spatialElementObjectType = NamingUtil.GetObjectTypeOverride(spatialElement, null);
                    string spatialElementLongName = NamingUtil.GetLongNameOverride(spatialElement, longName);
                    
                    double? spaceElevationWithFlooring = null;
                    double elevationWithFlooring = 0.0;
                    if (ParameterUtil.GetDoubleValueFromElement(spatialElement, null, "IfcElevationWithFlooring", out elevationWithFlooring) != null)
                        spaceElevationWithFlooring = UnitUtil.ScaleLength(elevationWithFlooring);
                    spaceHnd = IFCInstanceExporter.CreateSpace(file, GUIDUtil.CreateGUID(spatialElement),
                                                  ExporterCacheManager.OwnerHistoryHandle,
                                                  spatialElementName, spatialElementDescription, spatialElementObjectType,
                                                  extraParams.GetLocalPlacement(), repHnd, spatialElementLongName, Toolkit.IFCElementComposition.Element,
                                                  internalOrExternal, spaceElevationWithFlooring);

                    transaction2.Commit();
                }

                if (spaceHnd != null)
                {
                    productWrapper.AddSpace(spatialElement, spaceHnd, levelInfo, extraParams, true);
                    if (isArea)
                    {
                        Element areaScheme = spatialElementAsArea.AreaScheme;
                        if (areaScheme != null)
                        {
                            ElementId areaSchemeId = areaScheme.Id;
                            HashSet<IFCAnyHandle> areas = null;
                            if (!ExporterCacheManager.AreaSchemeCache.TryGetValue(areaSchemeId, out areas))
                            {
                                areas = new HashSet<IFCAnyHandle>();
                                ExporterCacheManager.AreaSchemeCache[areaSchemeId] = areas;
                            }
                            areas.Add(spaceHnd);
                        }
                    }
                }
            }

            // Save room handle for later use/relationships
            ExporterCacheManager.SpaceInfoCache.SetSpaceHandle(spatialElement, spaceHnd);

            // Find Ceiling as a Space boundary and keep the relationship in a cache for use later
            bool ret = GetCeilingSpaceBoundary(spatialElement, out results);

         if (!MathUtil.IsAlmostZero(dArea) && !(ExporterCacheManager.ExportOptionsCache.ExportAsCOBIE) &&
                !ExporterCacheManager.ExportOptionsCache.ExportAs2x3CoordinationView2 && !ExporterCacheManager.ExportOptionsCache.ExportBaseQuantities)
            {
                bool isDesignGrossArea = (string.Compare(spatialElementName, "GSA Design Gross Area") > 0);
                PropertyUtil.CreatePreCOBIEGSAQuantities(exporterIFC, spaceHnd, "GSA Space Areas", (isDesignGrossArea ? "GSA Design Gross Area" : "GSA BIM Area"), dArea);
            }

            // Export Classifications for SpatialElement for GSA/COBIE.
         if (ExporterCacheManager.ExportOptionsCache.ExportAsCOBIE)
            {
                ProjectInfo projectInfo = document.ProjectInformation;
                if (projectInfo != null)
                    CreateCOBIESpaceClassifications(exporterIFC, file, spaceHnd, projectInfo, spatialElement);
            }

            return true;
        }
Пример #56
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)
        {
            ElementType elemType    = element.Document.GetElement(element.GetTypeId()) as ElementType;
            IFCFile     file        = exporterIFC.GetFile();
            Options     geomOptions = GeometryUtil.GetIFCExportGeometryOptions();

            using (IFCTransaction transaction = new IFCTransaction(file))
            {
                using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element))
                {
                    using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                    {
                        IFCAnyHandle           localPlacement = setter.LocalPlacement;
                        StairRampContainerInfo stairRampInfo  = null;
                        ElementId hostId = GetStairOrRampHostId(exporterIFC, element as Railing);
                        if (hostId != ElementId.InvalidElementId)
                        {
                            stairRampInfo = ExporterCacheManager.StairRampContainerInfoCache.GetStairRampContainerInfo(hostId);
                            IFCAnyHandle stairRampLocalPlacement = stairRampInfo.LocalPlacements[0];
                            Transform    relTrf     = ExporterIFCUtils.GetRelativeLocalPlacementOffsetTransform(stairRampLocalPlacement, localPlacement);
                            Transform    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();

                        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>         subElementSolids        = subElementSolidMeshInfo.GetSolids();
                                IList <Mesh>          subElementMeshes        = subElementSolidMeshInfo.GetMeshes();
                                foreach (Solid subElementSolid in subElementSolids)
                                {
                                    solids.Add(subElementSolid);
                                }
                                foreach (Mesh subElementMesh in subElementMeshes)
                                {
                                    meshes.Add(subElementMesh);
                                }
                            }
                        }

                        ElementId           catId               = CategoryUtil.GetSafeCategoryId(element);
                        BodyData            bodyData            = null;
                        BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true);
                        bodyExporterOptions.TessellationLevel = BodyExporter.GetTessellationLevel();
                        //bodyExporterOptions.UseGroupsIfPossible = true;
                        //bodyExporterOptions.UseMappedGeometriesIfPossible = true;

                        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>();
                        foreach (Solid solid in solids)
                        {
                            geomObjects.Add(solid);
                        }
                        foreach (Mesh mesh in meshes)
                        {
                            geomObjects.Add(mesh);
                        }

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

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

                        IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle();

                        string instanceGUID        = GUIDUtil.CreateGUID(element);
                        string instanceName        = NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element));
                        string instanceDescription = NamingUtil.GetDescriptionOverride(element, null);
                        string instanceObjectType  = NamingUtil.GetObjectTypeOverride(element, exporterIFC.GetFamilyName());
                        string instanceTag         = NamingUtil.GetTagOverride(element, NamingUtil.CreateIFCElementId(element));

                        string railingType = IFCValidateEntry.GetValidIFCType(element, ifcEnumType);

                        IFCAnyHandle railing = IFCInstanceExporter.CreateRailing(file, instanceGUID, ownerHistory,
                                                                                 instanceName, instanceDescription, instanceObjectType, ecData.GetLocalPlacement(),
                                                                                 prodRep, instanceTag, railingType);

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

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

                        CategoryUtil.CreateMaterialAssociations(exporterIFC, railing, bodyData.MaterialIds);

                        // 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);
                                    CategoryUtil.CreateMaterialAssociations(exporterIFC, railingHndCopy, bodyData.MaterialIds);
                                }
                            }

                            ExporterCacheManager.StairRampContainerInfoCache.AddStairRampContainerInfo(hostId, stairRampInfo);
                        }
                    }
                    transaction.Commit();
                }
            }
        }
Пример #57
0
        /// <summary>
        /// Exports a roof to IfcRoof.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="ifcEnumType">The roof type.</param>
        /// <param name="roof">The roof element.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        public static void ExportRoof(ExporterIFC exporterIFC, string ifcEnumType, Element roof, GeometryElement geometryElement,
                                      ProductWrapper productWrapper)
        {
            if (roof == null || geometryElement == null)
            {
                return;
            }

            IFCFile file = exporterIFC.GetFile();

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

                using (PlacementSetter placementSetter = PlacementSetter.Create(exporterIFC, roof, null, null, overrideContainerId, overrideContainerHnd))
                {
                    using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                    {
                        // If the roof is an in-place family, we will allow any arbitrary orientation.  While this may result in some
                        // in-place "cubes" exporting with the wrong direction, it is unlikely that an in-place family would be
                        // used for this reason in the first place.
                        ecData.PossibleExtrusionAxes   = (roof is FamilyInstance) ? IFCExtrusionAxes.TryXYZ : IFCExtrusionAxes.TryZ;
                        ecData.AreInnerRegionsOpenings = true;
                        ecData.SetLocalPlacement(placementSetter.LocalPlacement);

                        ElementId categoryId = CategoryUtil.GetSafeCategoryId(roof);

                        BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow);
                        BodyData            bodyData;
                        IFCAnyHandle        representation = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC, roof,
                                                                                                                        categoryId, geometryElement, bodyExporterOptions, null, ecData, out bodyData);

                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(representation))
                        {
                            ecData.ClearOpenings();
                            return;
                        }

                        bool exportSlab = ecData.ScaledLength > MathUtil.Eps();

                        string       guid           = GUIDUtil.CreateGUID(roof);
                        IFCAnyHandle ownerHistory   = ExporterCacheManager.OwnerHistoryHandle;
                        IFCAnyHandle localPlacement = ecData.GetLocalPlacement();
                        //string predefinedType = GetIFCRoofType(ifcEnumType);
                        string predefinedType = IFCValidateEntry.GetValidIFCPredefinedTypeType(ifcEnumType, "NOTDEFINED", IFCEntityType.IfcRoofType.ToString());

                        IFCAnyHandle roofHnd = IFCInstanceExporter.CreateRoof(exporterIFC, roof, guid, ownerHistory,
                                                                              localPlacement, exportSlab ? null : representation, predefinedType);

                        // Export IfcRoofType
                        IFCExportInfoPair exportInfo = new IFCExportInfoPair(IFCEntityType.IfcRoof, IFCEntityType.IfcRoofType, predefinedType);
                        if (exportInfo.ExportType != IFCEntityType.UnKnown)
                        {
                            string overridePDefType;
                            if (ParameterUtil.GetStringValueFromElementOrSymbol(roof, "IfcExportType", out overridePDefType) == null) // change IFCType to consistent parameter of IfcExportType
                            {
                                if (ParameterUtil.GetStringValueFromElementOrSymbol(roof, "IfcType", out overridePDefType) == null)   // support IFCType for legacy support
                                {
                                    if (string.IsNullOrEmpty(predefinedType))
                                    {
                                        predefinedType = "NOTDEFINED";
                                    }
                                }
                            }

                            if (!string.IsNullOrEmpty(overridePDefType))
                            {
                                exportInfo.ValidatedPredefinedType = overridePDefType;
                            }
                            else
                            {
                                exportInfo.ValidatedPredefinedType = predefinedType;
                            }

                            IFCAnyHandle typeHnd = ExporterUtil.CreateGenericTypeFromElement(roof, exportInfo, file, ownerHistory, predefinedType, productWrapper);
                            ExporterCacheManager.TypeRelationsCache.Add(typeHnd, roofHnd);
                        }

                        productWrapper.AddElement(roof, roofHnd, placementSetter.LevelInfo, ecData, true, exportInfo);

                        // will export its host object materials later if it is a roof
                        if (!(roof is RoofBase))
                        {
                            CategoryUtil.CreateMaterialAssociation(exporterIFC, roofHnd, bodyData.MaterialIds);
                        }

                        if (exportSlab)
                        {
                            string       slabGUID = GUIDUtil.CreateSubElementGUID(roof, (int)IFCRoofSubElements.RoofSlabStart);
                            string       slabName = IFCAnyHandleUtil.GetStringAttribute(roofHnd, "Name") + ":1";
                            IFCAnyHandle slabLocalPlacementHnd = ExporterUtil.CopyLocalPlacement(file, localPlacement);

                            IFCAnyHandle slabHnd = IFCInstanceExporter.CreateSlab(exporterIFC, roof, slabGUID, ownerHistory,
                                                                                  slabLocalPlacementHnd, representation, slabRoofPredefinedType);
                            IFCAnyHandleUtil.OverrideNameAttribute(slabHnd, slabName);
                            Transform offsetTransform = (bodyData != null) ? bodyData.OffsetTransform : Transform.Identity;
                            OpeningUtil.CreateOpeningsIfNecessary(slabHnd, roof, ecData, offsetTransform,
                                                                  exporterIFC, slabLocalPlacementHnd, placementSetter, productWrapper);

                            ExporterUtil.RelateObject(exporterIFC, roofHnd, slabHnd);
                            IFCExportInfoPair slabRoofExportType = new IFCExportInfoPair(IFCEntityType.IfcSlab, slabRoofPredefinedType);

                            productWrapper.AddElement(null, slabHnd, placementSetter.LevelInfo, ecData, false, slabRoofExportType);
                            CategoryUtil.CreateMaterialAssociation(exporterIFC, slabHnd, bodyData.MaterialIds);

                            // Create type

                            IFCAnyHandle slabRoofTypeHnd = ExporterUtil.CreateGenericTypeFromElement(roof, slabRoofExportType, exporterIFC.GetFile(), ownerHistory, slabRoofPredefinedType, productWrapper);
                            ExporterCacheManager.TypeRelationsCache.Add(slabRoofTypeHnd, slabHnd);
                        }
                    }
                    tr.Commit();
                }
            }
        }
Пример #58
0
        /// <summary>
        /// Exports an element to IfcPile.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="element">The element.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="ifcEnumType">The string value represents the IFC type.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        public static void ExportPile(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement,
                                      string ifcEnumType, ProductWrapper productWrapper)
        {
            // export parts or not
            bool exportParts = PartExporter.CanExportParts(element);

            if (exportParts && !PartExporter.CanExportElementInPartExport(element, element.LevelId, false))
            {
                return;
            }

            IFCFile file = exporterIFC.GetFile();

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element))
                {
                    using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                    {
                        ecData.SetLocalPlacement(setter.LocalPlacement);

                        IFCAnyHandle prodRep = null;
                        ElementId    matId   = ElementId.InvalidElementId;
                        if (!exportParts)
                        {
                            ElementId catId = CategoryUtil.GetSafeCategoryId(element);


                            matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(geometryElement, exporterIFC, element);
                            BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true);
                            prodRep = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC,
                                                                                                 element, catId, geometryElement, bodyExporterOptions, null, ecData, true);
                            if (IFCAnyHandleUtil.IsNullOrHasNoValue(prodRep))
                            {
                                ecData.ClearOpenings();
                                return;
                            }
                        }

                        string instanceGUID        = GUIDUtil.CreateGUID(element);
                        string instanceName        = NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element));
                        string instanceDescription = NamingUtil.GetDescriptionOverride(element, null);
                        string instanceObjectType  = NamingUtil.GetObjectTypeOverride(element, exporterIFC.GetFamilyName());
                        string instanceTag         = NamingUtil.GetTagOverride(element, NamingUtil.CreateIFCElementId(element));
                        string pileType            = IFCValidateEntry.GetValidIFCType(element, ifcEnumType);

                        IFCAnyHandle pile = IFCInstanceExporter.CreatePile(file, instanceGUID, exporterIFC.GetOwnerHistoryHandle(),
                                                                           instanceName, instanceDescription, instanceObjectType, ecData.GetLocalPlacement(), prodRep, instanceTag, pileType, null);

                        if (exportParts)
                        {
                            PartExporter.ExportHostPart(exporterIFC, element, pile, productWrapper, setter, setter.LocalPlacement, null);
                        }
                        else
                        {
                            if (matId != ElementId.InvalidElementId)
                            {
                                CategoryUtil.CreateMaterialAssociation(exporterIFC, pile, matId);
                            }
                        }

                        productWrapper.AddElement(element, pile, setter, ecData, true);

                        OpeningUtil.CreateOpeningsIfNecessary(pile, element, ecData, null,
                                                              exporterIFC, ecData.GetLocalPlacement(), setter, productWrapper);
                    }
                }

                tr.Commit();
            }
        }
        /// <summary>
        /// Exports a gutter element.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="element">The element.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        public static void ExportGutter(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, ProductWrapper productWrapper)
        {
            IFCFile file = exporterIFC.GetFile();

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element))
                {
                    using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                    {
                        ecData.SetLocalPlacement(setter.LocalPlacement);

                        ElementId categoryId = CategoryUtil.GetSafeCategoryId(element);

                        BodyExporterOptions bodyExporterOptions = new BodyExporterOptions();
                        IFCAnyHandle bodyRep = BodyExporter.ExportBody(exporterIFC, element, categoryId, ElementId.InvalidElementId,
                            geometryElement, bodyExporterOptions, ecData).RepresentationHnd;
                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep))
                        {
                            if (ecData != null)
                                ecData.ClearOpenings();
                            return;
                        }

                        IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle();
                        string originalTag = NamingUtil.CreateIFCElementId(element);

                        // In Revit, we don't have a corresponding type, so we create one for every gutter.
                        IFCAnyHandle origin = ExporterUtil.CreateAxis2Placement3D(file);
                        IFCAnyHandle repMap3dHnd = IFCInstanceExporter.CreateRepresentationMap(file, origin, bodyRep);
                        List<IFCAnyHandle> repMapList = new List<IFCAnyHandle>();
                        repMapList.Add(repMap3dHnd);
                        string elementTypeName = NamingUtil.CreateIFCObjectName(exporterIFC, element);

                        string typeGuid = GUIDUtil.CreateSubElementGUID(element, (int) IFCHostedSweepSubElements.PipeSegmentType);
                        IFCAnyHandle style = IFCInstanceExporter.CreatePipeSegmentType(file, typeGuid, ownerHistory,
                            elementTypeName, null, null, null, repMapList, originalTag, 
                            elementTypeName, IFCPipeSegmentType.Gutter);
                        
                        List<IFCAnyHandle> representationMaps = GeometryUtil.GetRepresentationMaps(style);
                        IFCAnyHandle mappedItem = ExporterUtil.CreateDefaultMappedItem(file, representationMaps[0]);

                        ISet<IFCAnyHandle> representations = new HashSet<IFCAnyHandle>();
                        representations.Add(mappedItem);

                        IFCAnyHandle bodyMappedItemRep = RepresentationUtil.CreateBodyMappedItemRep(exporterIFC,
                            element, categoryId, exporterIFC.Get3DContextHandle("Body"), representations);
                        if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyMappedItemRep))
                            return;

                        List<IFCAnyHandle> shapeReps = new List<IFCAnyHandle>();
                        shapeReps.Add(bodyMappedItemRep);

                        IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, geometryElement, Transform.Identity);
                        if (boundingBoxRep != null)
                            shapeReps.Add(boundingBoxRep);
                        
                        IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, shapeReps);
                        IFCAnyHandle localPlacementToUse;
                        ElementId roomId = setter.UpdateRoomRelativeCoordinates(element, out localPlacementToUse);
                        if (roomId == ElementId.InvalidElementId)
                            localPlacementToUse = ecData.GetLocalPlacement();

                        string guid = GUIDUtil.CreateGUID(element);
                        string name = NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element));
                        string description = NamingUtil.GetDescriptionOverride(element, null);
                        string objectType = NamingUtil.GetObjectTypeOverride(element, elementTypeName);
                        string tag = NamingUtil.GetTagOverride(element, originalTag);

                        IFCAnyHandle elemHnd = IFCInstanceExporter.CreateFlowSegment(file, guid,
                            ownerHistory, name, description, objectType, localPlacementToUse, prodRep, tag);

                        bool containedInSpace = (roomId != ElementId.InvalidElementId);
                        productWrapper.AddElement(element, elemHnd, setter.LevelInfo, ecData, !containedInSpace);
                        
                        if (containedInSpace)
                            ExporterCacheManager.SpaceInfoCache.RelateToSpace(roomId, elemHnd);

                        // Associate segment with type.
                        ExporterCacheManager.TypeRelationsCache.Add(style, elemHnd);

                        OpeningUtil.CreateOpeningsIfNecessary(elemHnd, element, ecData, null,
                            exporterIFC, localPlacementToUse, setter, productWrapper);
                    }

                    tr.Commit();
                }
            }
        }
Пример #60
0
        /// <summary>
        /// Exports a ramp to IfcRamp, without decomposing into separate runs and landings.
        /// </summary>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="ifcEnumType">The ramp type.</param>
        /// <param name="ramp">The ramp element.</param>
        /// <param name="geometryElement">The geometry element.</param>
        /// <param name="numFlights">The number of flights for a multistory ramp.</param>
        /// <param name="productWrapper">The ProductWrapper.</param>
        public static void ExportRamp(ExporterIFC exporterIFC, string ifcEnumType, Element ramp, GeometryElement geometryElement,
                                      int numFlights, ProductWrapper productWrapper)
        {
            if (ramp == null || geometryElement == null)
            {
                return;
            }

            // Check the intended IFC entity or type name is in the exclude list specified in the UI
            Common.Enums.IFCEntityType elementClassTypeEnum = Common.Enums.IFCEntityType.IfcRamp;
            if (ExporterCacheManager.ExportOptionsCache.IsElementInExcludeList(elementClassTypeEnum))
            {
                return;
            }

            // TESTING
            foreach (GeometryObject geomObj in geometryElement)
            {
                Visibility visibility = geomObj.Visibility;
            }

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

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                using (PlacementSetter placementSetter = PlacementSetter.Create(exporterIFC, ramp))
                {
                    IFCAnyHandle contextOfItemsFootPrint = exporterIFC.Get3DContextHandle("FootPrint");
                    IFCAnyHandle contextOfItemsAxis      = exporterIFC.Get3DContextHandle("Axis");

                    Transform    trf          = ExporterIFCUtils.GetUnscaledTransform(exporterIFC, placementSetter.LocalPlacement);
                    IFCAnyHandle ownerHistory = ExporterCacheManager.OwnerHistoryHandle;

                    IList <(Solid body, Face largestTopFace)> rampFlights = null;
                    IList <Solid> landings = null;
                    if (IdentifyRampFlightAndLanding(geometryElement, out rampFlights, out landings))
                    {
                        string       rampGUID           = GUIDUtil.CreateGUID(ramp);
                        IFCAnyHandle rampLocalPlacement = placementSetter.LocalPlacement;
                        string       predefType         = "NOTDEFINED"; //Temporary
                        IFCAnyHandle rampContainerHnd   = IFCInstanceExporter.CreateRamp(exporterIFC, ramp, rampGUID, ownerHistory, rampLocalPlacement, null, predefType);
                        // Create appropriate type
                        IFCExportInfoPair exportType = new IFCExportInfoPair();
                        exportType.SetValueWithPair(IFCEntityType.IfcRamp);
                        IFCAnyHandle rampTypeHnd = ExporterUtil.CreateGenericTypeFromElement(ramp, exportType, exporterIFC.GetFile(), ownerHistory, predefType, productWrapper);
                        ExporterCacheManager.TypeRelationsCache.Add(rampTypeHnd, rampContainerHnd);
                        productWrapper.AddElement(ramp, rampContainerHnd, placementSetter.LevelInfo, null, true);

                        //Breakdown the Ramp into its components: RampFlights and Landings
                        int rampFlightIndex = 0;
                        int landingIndex    = 0;
                        HashSet <IFCAnyHandle> rampComponents = new HashSet <IFCAnyHandle>();
                        foreach ((Solid body, Face topFace)rampFlight in rampFlights)
                        {
                            using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                            {
                                ecData.AllowVerticalOffsetOfBReps = false;
                                ecData.SetLocalPlacement(ExporterUtil.CreateLocalPlacement(file, placementSetter.LocalPlacement, null));
                                ecData.ReuseLocalPlacement = true;
                                BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow);
                                BodyData            bodyData            = BodyExporter.ExportBody(exporterIFC, ramp, categoryId, ElementId.InvalidElementId, rampFlight.body, bodyExporterOptions, ecData);

                                IFCAnyHandle bodyRep = bodyData.RepresentationHnd;
                                if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep))
                                {
                                    ecData.ClearOpenings();
                                    continue;
                                }
                                IList <IFCAnyHandle> reps = new List <IFCAnyHandle>();
                                reps.Add(bodyRep);

                                //if (!ExporterCacheManager.ExportOptionsCache.ExportAsCoordinationView2)
                                //{
                                //   CreateWalkingLineAndFootprint(exporterIFC, run, bodyData, categoryId, trf, ref reps);
                                //}

                                Transform boundingBoxTrf         = (bodyData.OffsetTransform == null) ? Transform.Identity : bodyData.OffsetTransform.Inverse;
                                IList <GeometryObject> solidList = new List <GeometryObject>();
                                solidList.Add(rampFlight.body);
                                IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, solidList, boundingBoxTrf);
                                if (boundingBoxRep != null)
                                {
                                    reps.Add(boundingBoxRep);
                                }

                                IFCAnyHandle representation = IFCInstanceExporter.CreateProductDefinitionShape(exporterIFC.GetFile(), null, null, reps);

                                rampFlightIndex++;
                                string flightGUID     = GUIDUtil.CreateSubElementGUID(ramp, rampFlightIndex);
                                string origFlightName = IFCAnyHandleUtil.GetStringAttribute(rampContainerHnd, "Name") + " " + rampFlightIndex;
                                string flightName     = NamingUtil.GetOverrideStringValue(ramp, "IfcRampFlight.Name (" + rampFlightIndex + ")", origFlightName);

                                IFCAnyHandle flightLocalPlacement = ecData.GetLocalPlacement();
                                string       flightPredefType     = NamingUtil.GetOverrideStringValue(ramp, "IfcRampFlight.PredefinedType (" + rampFlightIndex + ")", null);

                                IFCAnyHandle rampFlightHnd = IFCInstanceExporter.CreateRampFlight(exporterIFC, null, flightGUID, ownerHistory, flightLocalPlacement,
                                                                                                  representation, flightPredefType);
                                IFCAnyHandleUtil.OverrideNameAttribute(rampFlightHnd, flightName);
                                rampComponents.Add(rampFlightHnd);

                                // Create type
                                IFCExportInfoPair flightEportType = new IFCExportInfoPair();
                                flightEportType.SetValueWithPair(IFCEntityType.IfcRampFlight);
                                IFCAnyHandle flightTypeHnd = IFCInstanceExporter.CreateGenericIFCType(flightEportType, null, exporterIFC.GetFile(), null, null, flightPredefType);
                                IFCAnyHandleUtil.OverrideNameAttribute(flightTypeHnd, flightName);
                                ExporterCacheManager.TypeRelationsCache.Add(flightTypeHnd, rampFlightHnd);

                                CategoryUtil.CreateMaterialAssociation(exporterIFC, rampFlightHnd, bodyData.MaterialIds);

                                IFCAnyHandle psetRampFlightCommonHnd = CreatePSetRampFlightCommon(exporterIFC, file, ramp, rampFlightIndex, rampFlight.topFace);

                                if (!IFCAnyHandleUtil.IsNullOrHasNoValue(psetRampFlightCommonHnd))
                                {
                                    HashSet <IFCAnyHandle> relatedObjects = new HashSet <IFCAnyHandle>()
                                    {
                                        rampFlightHnd
                                    };
                                    ExporterUtil.CreateRelDefinesByProperties(file, GUIDUtil.CreateGUID(), ownerHistory, null, null, relatedObjects, psetRampFlightCommonHnd);
                                }
                            }
                        }
                        foreach (Solid landing in landings)
                        {
                            using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                            {
                                ecData.AllowVerticalOffsetOfBReps = false;
                                ecData.SetLocalPlacement(ExporterUtil.CreateLocalPlacement(file, placementSetter.LocalPlacement, null));
                                ecData.ReuseLocalPlacement = true;
                                BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow);
                                BodyData            bodyData            = BodyExporter.ExportBody(exporterIFC, ramp, categoryId, ElementId.InvalidElementId, landing, bodyExporterOptions, ecData);

                                IFCAnyHandle bodyRep = bodyData.RepresentationHnd;
                                if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep))
                                {
                                    ecData.ClearOpenings();
                                    continue;
                                }
                                IList <IFCAnyHandle> reps = new List <IFCAnyHandle>();
                                reps.Add(bodyRep);

                                //if (!ExporterCacheManager.ExportOptionsCache.ExportAsCoordinationView2)
                                //{
                                //   CreateWalkingLineAndFootprint(exporterIFC, run, bodyData, categoryId, trf, ref reps);
                                //}

                                Transform boundingBoxTrf         = (bodyData.OffsetTransform == null) ? Transform.Identity : bodyData.OffsetTransform.Inverse;
                                IList <GeometryObject> solidList = new List <GeometryObject>();
                                solidList.Add(landing);
                                IFCAnyHandle boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, solidList, boundingBoxTrf);
                                if (boundingBoxRep != null)
                                {
                                    reps.Add(boundingBoxRep);
                                }

                                IFCAnyHandle representation = IFCInstanceExporter.CreateProductDefinitionShape(exporterIFC.GetFile(), null, null, reps);

                                landingIndex++;
                                string landingGUID     = GUIDUtil.CreateSubElementGUID(ramp, landingIndex);
                                string origLandingName = IFCAnyHandleUtil.GetStringAttribute(rampContainerHnd, "Name") + " " + landingIndex;
                                string landingName     = NamingUtil.GetOverrideStringValue(ramp, "IfcRampLanding.Name (" + landingIndex + ")", origLandingName);

                                IFCAnyHandle landingLocalPlacement = ecData.GetLocalPlacement();
                                string       landingPredefType     = "LANDING";

                                IFCAnyHandle rampLandingHnd = IFCInstanceExporter.CreateSlab(exporterIFC, ramp, landingGUID, ownerHistory, landingLocalPlacement,
                                                                                             representation, landingPredefType);
                                IFCAnyHandleUtil.OverrideNameAttribute(rampLandingHnd, landingName);
                                rampComponents.Add(rampLandingHnd);

                                // Create type
                                IFCExportInfoPair landingEportType = new IFCExportInfoPair();
                                landingEportType.SetValueWithPair(IFCEntityType.IfcSlab);
                                IFCAnyHandle landingTypeHnd = IFCInstanceExporter.CreateGenericIFCType(landingEportType, null, exporterIFC.GetFile(), null, null, landingPredefType);
                                IFCAnyHandleUtil.OverrideNameAttribute(landingTypeHnd, landingName);
                                ExporterCacheManager.TypeRelationsCache.Add(landingTypeHnd, rampLandingHnd);

                                CategoryUtil.CreateMaterialAssociation(exporterIFC, rampLandingHnd, bodyData.MaterialIds);

                                IFCAnyHandle psetSlabCommonHnd = CreatePSetRampLandingCommon(exporterIFC, file, ramp, landingIndex);

                                if (!IFCAnyHandleUtil.IsNullOrHasNoValue(psetSlabCommonHnd))
                                {
                                    HashSet <IFCAnyHandle> relatedObjects = new HashSet <IFCAnyHandle>()
                                    {
                                        rampLandingHnd
                                    };
                                    ExporterUtil.CreateRelDefinesByProperties(file, GUIDUtil.CreateGUID(), ownerHistory, null, null, relatedObjects, psetSlabCommonHnd);
                                }
                            }
                        }

                        if (rampComponents.Count > 0)
                        {
                            IFCInstanceExporter.CreateRelAggregates(file, GUIDUtil.CreateGUID(), ownerHistory, null, null, rampContainerHnd, rampComponents);
                        }
                    }
                    else
                    {
                        using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                        {
                            ecData.SetLocalPlacement(placementSetter.LocalPlacement);
                            ecData.ReuseLocalPlacement = false;

                            GeometryElement rampGeom = GeometryUtil.GetOneLevelGeometryElement(geometryElement, numFlights);

                            BodyData bodyData;

                            BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true, ExportOptionsCache.ExportTessellationLevel.ExtraLow);
                            IFCAnyHandle        representation      = RepresentationUtil.CreateAppropriateProductDefinitionShape(exporterIFC,
                                                                                                                                 ramp, categoryId, rampGeom, bodyExporterOptions, null, ecData, out bodyData);

                            if (IFCAnyHandleUtil.IsNullOrHasNoValue(representation))
                            {
                                ecData.ClearOpenings();
                                return;
                            }

                            string       containedRampGuid           = GUIDUtil.CreateSubElementGUID(ramp, (int)IFCRampSubElements.ContainedRamp);
                            IFCAnyHandle containedRampLocalPlacement = ExporterUtil.CreateLocalPlacement(file, ecData.GetLocalPlacement(), null);
                            string       rampType = GetIFCRampType(ifcEnumType);

                            List <IFCAnyHandle> components = new List <IFCAnyHandle>();
                            IList <IFCExtrusionCreationData> componentExtrusionData = new List <IFCExtrusionCreationData>();
                            IFCAnyHandle containedRampHnd = IFCInstanceExporter.CreateRamp(exporterIFC, ramp, containedRampGuid, ownerHistory,
                                                                                           containedRampLocalPlacement, representation, rampType);
                            components.Add(containedRampHnd);
                            componentExtrusionData.Add(ecData);
                            //productWrapper.AddElement(containedRampHnd, placementSetter.LevelInfo, ecData, false);
                            CategoryUtil.CreateMaterialAssociation(exporterIFC, containedRampHnd, bodyData.MaterialIds);

                            string       guid           = GUIDUtil.CreateGUID(ramp);
                            IFCAnyHandle localPlacement = ecData.GetLocalPlacement();

                            IFCAnyHandle rampHnd = IFCInstanceExporter.CreateRamp(exporterIFC, ramp, guid, ownerHistory,
                                                                                  localPlacement, null, rampType);

                            productWrapper.AddElement(ramp, rampHnd, placementSetter.LevelInfo, ecData, true);

                            StairRampContainerInfo stairRampInfo = new StairRampContainerInfo(rampHnd, components, localPlacement);
                            ExporterCacheManager.StairRampContainerInfoCache.AddStairRampContainerInfo(ramp.Id, stairRampInfo);

                            ExportMultistoryRamp(exporterIFC, ramp, numFlights, rampHnd, components, componentExtrusionData, placementSetter,
                                                 productWrapper);
                        }
                    }
                }
                tr.Commit();
            }
        }