Beispiel #1
0
 /// <summary>
 /// Copies a BodyData object.
 /// </summary>
 /// <param name="representationHnd">
 /// The representation handle.
 /// </param>
 /// <param name="offsetTransform">
 /// The offset transform.
 /// </param>
 /// <param name="materialIds">
 /// The material ids.
 /// </param>
 public BodyData(BodyData bodyData)
 {
     this.m_RepresentationHnd = bodyData.RepresentationHnd;
     this.m_ShapeRepresentationType = bodyData.m_ShapeRepresentationType;
     this.m_OffsetTransform = bodyData.OffsetTransform;
     this.m_MaterialIds = bodyData.MaterialIds;
 }
        /// <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 (!exporterIFC.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);
            }

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

            if (bodyReps.Count == 0)
                return null;
            return IFCInstanceExporter.CreateProductDefinitionShape(exporterIFC.GetFile(), null, null, bodyReps);
        }
        /// <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();
            double  scale = exporterIFC.LinearScale;

            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.get_EndPoint(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 (IFCPlacementSetter setter = IFCPlacementSetter.Create(exporterIFC, element, null, canExportAxis ? orientTrf : null, ExporterUtil.GetBaseLevelIdForElement(element)))
                {
                    IFCAnyHandle          localPlacement = setter.GetPlacement();
                    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 = -offsetTransform.Origin / scale;
                            }
                            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));

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

                        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);

                        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();
            }
        }
Beispiel #4
0
        /// <summary>
        /// Exports list of geometries to IFC body representation.
        /// </summary>
        /// <param name="application">The Revit application.</param>
        /// <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(Autodesk.Revit.ApplicationServices.Application application, 
            ExporterIFC exporterIFC,
            Element element, 
            ElementId categoryId,
            IList<GeometryObject> geometryListIn,
            BodyExporterOptions options,
            IFCExtrusionCreationData exportBodyParams) 
        {
            BodyData bodyData = new BodyData();
            if (geometryListIn.Count == 0)
                return bodyData;

            Document document = element.Document;
            bool tryToExportAsExtrusion = options.TryToExportAsExtrusion;
            bool canExportSolidModelRep = false;

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

            double eps = application.VertexTolerance * scale;

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

            bool allFaces = true;
            foreach (GeometryObject geomObject in geometryListIn)
            {
                try
                {
                    bool split = false;
                    if (geomObject is Solid)
                    {
                        Solid solid = geomObject as Solid;
                        IList<Solid> splitVolumes = SolidUtils.SplitVolumes(solid);
                        allFaces = false;

                        if (splitVolumes != null && splitVolumes.Count != 0)
                        {
                            split = true;
                            foreach (Solid currSolid in splitVolumes)
                            {
                                splitGeometryList.Add(currSolid);
                                // The geometry element created by SplitVolumesis a copy which will have its own allocated
                                // membership - this needs to be stored and disposed of (see AllocatedGeometryObjectCache
                                // for details)
                                ExporterCacheManager.AllocatedGeometryObjectCache.AddGeometryObject(currSolid);
                            }
                        }
                    }
                    else if (allFaces && !(geomObject is Face))
                        allFaces = false;

                    if (!split)
                        splitGeometryList.Add(geomObject);
                }
                catch
                {
                    splitGeometryList.Add(geomObject);
                }
            }

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

            IList<int> exportAsBRep = new List<int>();
            IList<int> exportAsExtrusion = new List<int>();
            
            using (IFCTransaction tr = new IFCTransaction(file))
            {
                if (tryToExportAsExtrusion)
                {
                    // 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 splitGeometryList)
                        {
                            faces.Add(geometryObject as Face);
                        }
                    }

                    int numExtrusionsToCreate = allFaces ? 1 : splitGeometryList.Count;

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

                        IFCExtrusionAxes axesToExtrudeIn = exportBodyParams != null ? exportBodyParams.PossibleExtrusionAxes : IFCExtrusionAxes.TryDefault;
                        XYZ directionToExtrudeIn = XYZ.Zero;
                        if (exportBodyParams != null && exportBodyParams.HasCustomAxis)
                            directionToExtrudeIn = exportBodyParams.CustomAxis;

                        IFCExtrusionCalculatorOptions extrusionOptions =
                           new IFCExtrusionCalculatorOptions(exporterIFC, axesToExtrudeIn, directionToExtrudeIn, scale);

                        if (allFaces)
                            extrusionList = IFCExtrusionCalculatorUtils.CalculateExtrusionData(extrusionOptions, faces);
                        else
                            extrusionList = IFCExtrusionCalculatorUtils.CalculateExtrusionData(extrusionOptions, splitGeometryList[ii]);

                        if (extrusionList.Count == 0)
                        {
                            if (!canExportSolidModelRep)
                            {
                                tryToExportAsExtrusion = false;
                                break;
                            }
                            exportAsBRep.Add(ii);
                        }
                        else
                        {
                            extrusionLists.Add(extrusionList);
                            exportAsExtrusion.Add(ii);
                        }
                    }

                    int numCreatedExtrusions = extrusionLists.Count;
                    for (int ii = 0; (ii < numCreatedExtrusions) && tryToExportAsExtrusion; ii++)
                    {
                        int geomIndex = exportAsExtrusion[ii];
                        bodyData.AddMaterial(SetBestMaterialIdInExporter(splitGeometryList[geomIndex], exporterIFC));

                        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)
                                {
                                    double zOff = (whichBasis == IFCExtrusionBasis.BasisZ) ? (1.0 - Math.Abs(extrusionDirection[2])) : Math.Abs(extrusionDirection[2]);
                                    double scaledAngle = Math.Asin(zOff) * 180 / Math.PI;
                                    exportBodyParams.Slope = scaledAngle;
                                    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 = height * scale;
                                        exportBodyParams.ScaledWidth = width * scale;
                                    }

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

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

                        if (!exportedAsExtrusion)
                        {
                            if (!canExportSolidModelRep)
                            {
                                tryToExportAsExtrusion = false;
                                break;
                            }
                            exportAsBRep.Add(ii);
                        }
                    }
                }

                if ((exportAsBRep.Count == 0) && tryToExportAsExtrusion)
                {
                    int sz = bodyItems.Count();
                    for (int ii = 0; ii < sz; ii++)
                        BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, document, bodyItems[ii], materialIdsForExtrusions[ii]);

                    bodyData.RepresentationHnd =
                        RepresentationUtil.CreateSweptSolidRep(exporterIFC, element, categoryId, contextOfItems, bodyItems, bodyData.RepresentationHnd);
                }

                if (tryToExportAsExtrusion)
                    tr.Commit();
                else
                    tr.RollBack();

                if ((exportAsBRep.Count == 0) && tryToExportAsExtrusion)
                    return bodyData;
            }
            
            // 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)
                exportAsBRep.Clear();

            // 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.
            // We will only do this if we didn't create any extrusions at all.
            using (IFCTransformSetter transformSetter = IFCTransformSetter.Create())
            {
                if (exportBodyParams != null && (exportAsBRep.Count == 0))
                    bodyData.BrepOffsetTransform = transformSetter.InitializeFromBoundingBox(exporterIFC, splitGeometryList, exportBodyParams);

                return ExportBodyAsBRep(exporterIFC, splitGeometryList, exportAsBRep, bodyItems, element, categoryId, contextOfItems, eps, options, bodyData);
            }
        }
Beispiel #5
0
        private static bool ProcessGroupMembership(ExporterIFC exporterIFC, IFCFile file, Element element, ElementId categoryId, IFCAnyHandle contextOfItems, 
            IList<GeometryObject> geomList, BodyData bodyDataIn,
            out BodyGroupKey groupKey, out BodyGroupData groupData, out BodyData bodyData)
        {
            // Set back to true if all checks are passed.
            bool useGroupsIfPossible = false;

            groupKey = null;
            groupData = null;
            bodyData = null;

            Group group = element.Group;
            if (group != null)
            {
                ElementId elementId = element.Id;

                bool pristineGeometry = true;
                foreach (GeometryObject geomObject in geomList)
                {
                    try
                    {
                        ICollection<ElementId> generatingElementIds = element.GetGeneratingElementIds(geomObject);
                        int numGeneratingElements = generatingElementIds.Count;
                        if ((numGeneratingElements > 1) || (numGeneratingElements == 1 && (generatingElementIds.First() != elementId)))
                        {
                            pristineGeometry = false;
                            break;
                        }
                    }
                    catch
                    {
                        pristineGeometry = false;
                        break;
                    }
                }

                if (pristineGeometry)
                {
                    groupKey = new BodyGroupKey();

                    IList<ElementId> groupMemberIds = group.GetMemberIds();
                    int numMembers = groupMemberIds.Count;
                    for (int idx = 0; idx < numMembers; idx++)
                    {
                        if (groupMemberIds[idx] == elementId)
                        {
                            groupKey.GroupMemberIndex = idx;
                            break;
                        }
                    }
                    if (groupKey.GroupMemberIndex >= 0)
                    {
                        groupKey.GroupTypeId = group.GetTypeId();

                        groupData = ExporterCacheManager.GroupElementGeometryCache.Find(groupKey);
                        if (groupData == null)
                        {
                            groupData = new BodyGroupData();
                            useGroupsIfPossible = true;
                        }
                        else
                        {
                            IList<IFCAnyHandle> groupBodyItems = new List<IFCAnyHandle>();
                            foreach (IFCAnyHandle mappedRepHnd in groupData.Handles)
                            {
                                IFCAnyHandle mappedItemHnd = ExporterUtil.CreateDefaultMappedItem(file, mappedRepHnd);
                                groupBodyItems.Add(mappedItemHnd);
                            }

                            bodyData = new BodyData(bodyDataIn);
                            bodyData.RepresentationHnd = RepresentationUtil.CreateBodyMappedItemRep(exporterIFC, element, categoryId, contextOfItems, groupBodyItems);
                            return true;
                        }
                    }
                }
            }
            return useGroupsIfPossible;
        }
Beispiel #6
0
        /// <summary>
        /// Creates a Brep product definition shape representation.
        /// </summary>
        /// <param name="application">The Revit application object.</param>
        /// <param name="exporterIFC">The ExporterIFC object.</param>
        /// <param name="categoryId">The category id.</param>
        /// <param name="geometryObject">The geometry object.</param>
        /// <param name="extraReps">Extra representations (e.g. Axis, Footprint).  May be null.</param>
        /// <param name="options">The settings for how to export the body.</param>
        /// <param name="extrusionCreationData">The extrusion creation data.</param>
        /// <param name="bodyData">The body data.</param>
        /// <returns>The handle.</returns>
        public static IFCAnyHandle CreateBRepProductDefinitionShape(Autodesk.Revit.ApplicationServices.Application application,
            ExporterIFC exporterIFC, Element element, ElementId categoryId,
            IList<GeometryObject> geometryObjectIn, IList<IFCAnyHandle> extraReps,
            BodyExporterOptions bodyExporterOptions, IFCExtrusionCreationData extrusionCreationData, out BodyData bodyData)
        {

            bodyData = BodyExporter.ExportBody(application, exporterIFC, element, categoryId, geometryObjectIn,
                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);
            }

            if (bodyReps.Count == 0)
                return null;
            return IFCInstanceExporter.CreateProductDefinitionShape(exporterIFC.GetFile(), null, null, bodyReps);
        }
Beispiel #7
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<int> exportAsBRep, IList<IFCAnyHandle> bodyItems,
            Element element, ElementId categoryId, IFCAnyHandle contextOfItems, double eps, BodyExporterOptions options, BodyData bodyDataIn)
        {
            bool exportAsBReps = true;
            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>();

            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;
            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;
            
            for (int index = 0; index < numGeoms; index++)
            {
                GeometryObject geomObject = selectiveBRepExport ? splitGeometryList[exportAsBRep[index]] : splitGeometryList[index];
                startIndexForObject.Add(currentFaceHashSetList.Count);

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

                bool exportedAsSolid = false;
                if (exportAsBReps || isCoarse)
                {
                    exportedAsSolid = ExportBodyAsSolid(exporterIFC, element, options, currentFaceHashSetList, geomObject);
                }
               
                if (!exportedAsSolid)
                {
                    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)
                        {
                            if ((currentFaceSet.Count < 4) || !CanCreateClosedShell(currentFaceSet))
                            {
                                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 brepIndex = 0;
                                    for (int fixIndex = 0; fixIndex < numGeoms; fixIndex++)
                                    {
                                        if ((brepIndex < numBRepsToExport) && (exportAsBRep[brepIndex] == fixIndex))
                                        {
                                            brepIndex++;
                                            continue;
                                        }
                                        exportAsBRep.Add(fixIndex);
                                    }
                                    numBRepsToExport = exportAsBRep.Count;
                                }
                            }
                        }

                        currentFaceHashSetList.Add(new HashSet<IFCAnyHandle>(currentFaceSet));
                    }
                }
            }
            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];

                    IFCAnyHandle faceOuter = IFCInstanceExporter.CreateClosedShell(file, currentFaceHashSet);
                    IFCAnyHandle brepHnd = RepresentationUtil.CreateFacetedBRep(exporterIFC, document, faceOuter, materialIds[matToUse]);
                    
                    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);
                    }
                }
            }

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

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

            return bodyData;
        }
Beispiel #8
0
 /// <summary>
 /// Copies a BodyData object.
 /// </summary>
 /// <param name="representationHnd">
 /// The representation handle.
 /// </param>
 /// <param name="brepOffsetTransform">
 /// The offset transform.
 /// </param>
 /// <param name="materialIds">
 /// The material ids.
 /// </param>
 public BodyData(BodyData bodyData)
 {
     this.m_RepresentationHnd   = bodyData.RepresentationHnd;
     this.m_BrepOffsetTransform = bodyData.BrepOffsetTransform;
     this.m_MaterialIds         = bodyData.MaterialIds;
 }
Beispiel #9
0
        /// <summary>
        /// Creates a Brep product definition shape representation.
        /// </summary>
        /// <remarks>
        /// It will try to export the geometry as an extrusion if it is not exported as IFC 2x2 version.
        /// </remarks>
        /// <param name="application">
        /// The Revit application object.
        /// </param>
        /// <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 CreateBRepProductDefinitionShape(Autodesk.Revit.ApplicationServices.Application application,
            ExporterIFC exporterIFC, Element element, ElementId categoryId,
            GeometryElement geometryElement, BodyExporterOptions bodyExporterOptions, IList<IFCAnyHandle> extraReps, IFCExtrusionCreationData extrusionCreationData,
            out BodyData bodyData)
        {
            SolidMeshGeometryInfo info = null;
            IList<GeometryObject> solids = new List<GeometryObject>();

            if (!exporterIFC.ExportAs2x2)
            {
                info = GeometryUtil.GetSolidMeshGeometry(geometryElement, Transform.Identity);
                IList<Mesh> meshes = info.GetMeshes();
                if (meshes.Count == 0)
                {
                    IList<Solid> solidList = info.GetSolids();
                    foreach (Solid solid in solidList)
                    {
                        solids.Add(solid);
                    }
                }
            }

            IFCAnyHandle ret = null;
            if (solids.Count == 0)
            {
                IList<GeometryObject> geometryList = new List<GeometryObject>();
                geometryList.Add(geometryElement);
                ret = CreateBRepProductDefinitionShape(application, exporterIFC, element, categoryId,
                    geometryList, extraReps, bodyExporterOptions, extrusionCreationData, out bodyData);
            }
            else
            {
                bodyExporterOptions.TryToExportAsExtrusion = true;
                ret = CreateBRepProductDefinitionShape(application, exporterIFC, element, categoryId,
                    solids, extraReps, bodyExporterOptions, extrusionCreationData, out bodyData);
            }
            return ret;
        }
        /// <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;
            
            // This will default to false for now in all cases, as swept solids are not included in CV2.0.
            bool tryToExportAsSweptSolid = options.TryToExportAsSweptSolid;
            
            IFCFile file = exporterIFC.GetFile();
            IFCAnyHandle contextOfItems = exporterIFC.Get3DContextHandle("Body");
            double scale = exporterIFC.LinearScale;

            double eps = element.Document.Application.VertexTolerance * scale;

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

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

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

            bool hasExtrusions = false;
            bool hasSweptSolids = false;

            XYZ unscaledTrfOrig = new XYZ();
            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 (IFCTransformSetter transformSetter = IFCTransformSetter.Create())
                {
                    // We may need to get the original values back, in case the export rolls back.
                    IFCLocalPlacementBackup localPlacementBackup = null;

                    if (options.AllowOffsetTransform && exportBodyParams!= null)
                    {
                        localPlacementBackup = new IFCLocalPlacementBackup(exportBodyParams.GetLocalPlacement());
                        bodyData.OffsetTransform = transformSetter.InitializeFromBoundingBox(exporterIFC, geometryList, exportBodyParams);
                    }

                    if (tryToExportAsExtrusion)
                    {
                        // 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);
                            }
                        }

                        int numExtrusionsToCreate = allFaces ? 1 : geometryList.Count;

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

                            IFCExtrusionAxes axesToExtrudeIn = exportBodyParams != null ? exportBodyParams.PossibleExtrusionAxes : IFCExtrusionAxes.TryDefault;
                            XYZ directionToExtrudeIn = XYZ.Zero;
                            if (exportBodyParams != null && exportBodyParams.HasCustomAxis)
                                directionToExtrudeIn = exportBodyParams.CustomAxis;

                            IFCExtrusionCalculatorOptions extrusionOptions =
                               new IFCExtrusionCalculatorOptions(exporterIFC, axesToExtrudeIn, directionToExtrudeIn, scale);

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

                            if (extrusionList.Count == 0)
                            {
                                if (tryToExportAsSweptSolid)
                                    exportAsSweptSolid.Add(ii);
                                else if (!canExportSolidModelRep)
                                {
                                    tryToExportAsExtrusion = false;
                                    break;
                                }
                                else
                                    exportAsBRep.Add(ii);
                            }
                            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 = height * scale;
                                            exportBodyParams.ScaledWidth = width * scale;
                                        }

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

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

                            if (!exportedAsExtrusion)
                            {
                                if (tryToExportAsSweptSolid)
                                    exportAsSweptSolid.Add(ii);
                                else if (!canExportSolidModelRep)
                                {
                                    tryToExportAsExtrusion = false;
                                    break;
                                }
                                else
                                    exportAsBRep.Add(ii);
                            }
                        }
                    }

                    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;
                            // TODO: allFaces to SweptSolid
                            if (solid != null)
                            {
                                // TODO: other types of Axes
                                XYZ normal = new XYZ(0, 0, 1);
                                SweptSolidExporter sweptSolidExporter = SweptSolidExporter.Create(exporterIFC, element, solid, normal);
                                if (sweptSolidExporter != null)
                                {
                                    IFCAnyHandle sweptHandle = sweptSolidExporter.RepresentationItem;
                                    if (!IFCAnyHandleUtil.IsNullOrHasNoValue(sweptHandle))
                                    {
                                        bodyItems.Add(sweptHandle);
                                        materialIdsForExtrusions.Add(exporterIFC.GetMaterialIdForCurrentExportState());
                                        exported = true;
                                        if (sweptSolidExporter.IsExtrusion)
                                            hasExtrusions = true;
                                        else
                                            hasSweptSolids = true;
                                    }
                                }
                            }

                            if (!exported)
                                exportAsBRep.Add(ii);
                        }
                    }

                    bool exportSucceeded = (exportAsBRep.Count == 0) && (tryToExportAsExtrusion || tryToExportAsSweptSolid) && (hasExtrusions || hasSweptSolids);
                    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 (hasExtrusions && !hasSweptSolids)
                        {
                            bodyData.RepresentationHnd =
                                RepresentationUtil.CreateSweptSolidRep(exporterIFC, element, categoryId, contextOfItems, bodyItems, bodyData.RepresentationHnd);
                            bodyData.ShapeRepresentationType = ShapeRepresentationType.SweptSolid;
                        }
                        else if (hasSweptSolids && !hasExtrusions)
                        {
                            bodyData.RepresentationHnd =
                                RepresentationUtil.CreateAdvancedSweptSolidRep(exporterIFC, element, categoryId, contextOfItems, bodyItems, bodyData.RepresentationHnd);
                            bodyData.ShapeRepresentationType = ShapeRepresentationType.AdvancedSweptSolid;
                        }
                        else
                        {
                            bodyData.RepresentationHnd =
                                RepresentationUtil.CreateSolidModelRep(exporterIFC, element, categoryId, contextOfItems, bodyItems);
                            bodyData.ShapeRepresentationType = ShapeRepresentationType.SolidModel;
                        }
                        
                        // TODO: include BRep, CSG, Clipping
                        tr.Commit();
                        return bodyData;
                    }
                    }

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

                        // Revert to the original local placement, and re-set the relative placement, as the rollback may delete either.
                        if (localPlacementBackup != null)
                        {
                           IFCAnyHandle origLocalPlacement = localPlacementBackup.Restore();
                           if (!IFCAnyHandleUtil.IsNullOrHasNoValue(origLocalPlacement))
                               exportBodyParams.SetLocalPlacement(origLocalPlacement);
                        }
                    }
                    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)
                    exportAsBRep.Clear();
            }

            using (IFCTransaction tr = new IFCTransaction(file))
            {
                using (IFCTransformSetter transformSetter = IFCTransformSetter.Create())
                {
                    if (exportBodyParams != null && (exportAsBRep.Count == 0))
                        bodyData.OffsetTransform = transformSetter.InitializeFromBoundingBox(exporterIFC, geometryList, exportBodyParams);

                    BodyData retBodyData = ExportBodyAsBRep(exporterIFC, geometryList, exportAsBRep, bodyItems, element, categoryId, overrideMaterialId, contextOfItems, eps, options, bodyData);
                    if (retBodyData != null)
                        tr.Commit();
                    else
                        tr.RollBack();
                    return retBodyData;
                }
            }
        }
Beispiel #11
0
 /// <summary>
 /// Copies a BodyData object.
 /// </summary>
 /// <param name="representationHnd">
 /// The representation handle.
 /// </param>
 /// <param name="brepOffsetTransform">
 /// The offset transform.
 /// </param>
 /// <param name="materialIds">
 /// The material ids.
 /// </param>
 public BodyData(BodyData bodyData)
 {
     this.m_RepresentationHnd = bodyData.RepresentationHnd;
     this.m_BrepOffsetTransform = bodyData.BrepOffsetTransform;
     this.m_MaterialIds = bodyData.MaterialIds;
 }
        /// <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 (IFCPlacementSetter setter = IFCPlacementSetter.Create(exporterIFC, element, null, null, ExporterUtil.GetBaseLevelIdForElement(element)))
                {
                    using (IFCExtrusionCreationData ecData = new IFCExtrusionCreationData())
                    {
                        IFCAnyHandle           localPlacement = setter.GetPlacement();
                        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 relativePlacement     = ExporterUtil.CreateAxis2Placement3D(file, inverseTrf.Origin, inverseTrf.BasisZ, inverseTrf.BasisX);
                            IFCAnyHandle railingLocalPlacement = ExporterUtil.CreateLocalPlacement(file, stairRampLocalPlacement, relativePlacement);
                            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));

                                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));
                        Toolkit.IFCRailingType railingType = GetIFCRailingType(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();
                }
            }
        }
        /// <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 (IFCPlacementSetter setter = IFCPlacementSetter.Create(exporterIFC, element, null, null, ExporterUtil.GetBaseLevelIdForElement(element)))
                {
                    IFCAnyHandle localPlacementToUse = setter.GetPlacement();
                    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;
                        if (FamilyExporterUtil.IsFurnishingElementSubType(exportType))
                        {
                            instanceHandle = IFCInstanceExporter.CreateFurnishingElement(file, instanceGUID, ownerHistory,
                                                                                         instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceTag);
                        }
                        else if (FamilyExporterUtil.IsDistributionFlowElementSubType(exportType))
                        {
                            instanceHandle = IFCInstanceExporter.CreateDistributionFlowElement(file, instanceGUID, ownerHistory,
                                                                                               instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceTag);
                        }
                        else if (FamilyExporterUtil.IsEnergyConversionDeviceSubType(exportType))
                        {
                            instanceHandle = IFCInstanceExporter.CreateEnergyConversionDevice(file, instanceGUID, ownerHistory,
                                                                                              instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceTag);
                        }
                        else if (FamilyExporterUtil.IsFlowFittingSubType(exportType))
                        {
                            instanceHandle = IFCInstanceExporter.CreateFlowFitting(file, instanceGUID, ownerHistory,
                                                                                   instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceTag);
                        }
                        else if (FamilyExporterUtil.IsFlowMovingDeviceSubType(exportType))
                        {
                            instanceHandle = IFCInstanceExporter.CreateFlowMovingDevice(file, instanceGUID, ownerHistory,
                                                                                        instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceTag);
                        }
                        else if (FamilyExporterUtil.IsFlowSegmentSubType(exportType))
                        {
                            instanceHandle = IFCInstanceExporter.CreateFlowSegment(file, instanceGUID, ownerHistory,
                                                                                   instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceTag);
                        }
                        else if (FamilyExporterUtil.IsFlowStorageDeviceSubType(exportType))
                        {
                            instanceHandle = IFCInstanceExporter.CreateFlowStorageDevice(file, instanceGUID, ownerHistory,
                                                                                         instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceTag);
                        }
                        else if (FamilyExporterUtil.IsFlowTerminalSubType(exportType))
                        {
                            instanceHandle = IFCInstanceExporter.CreateFlowTerminal(file, instanceGUID, ownerHistory,
                                                                                    instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceTag);
                        }
                        else if (FamilyExporterUtil.IsFlowTreatmentDeviceSubType(exportType))
                        {
                            instanceHandle = IFCInstanceExporter.CreateFlowTreatmentDevice(file, instanceGUID, ownerHistory,
                                                                                           instanceName, instanceDescription, instanceObjectType, localPlacementToUse, productRepresentation, instanceTag);
                        }
                        else if (FamilyExporterUtil.IsFlowControllerSubType(exportType))
                        {
                            instanceHandle = IFCInstanceExporter.CreateFlowController(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)
                        {
                            exporterIFC.RelateSpatialElement(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);
        }
Beispiel #14
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,
                                      IFCPlacementSetter 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;
            }

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

            ElementId partExportLevel = null;

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

            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 = IFCPlacementSetter.Create(exporterIFC, partElement, null, orientationTrf, partExportLevel);
                        partPlacement             = standalonePlacementSetter.GetPlacement();
                    }
                    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);

                        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;
                            IFCExportType exportType = ExporterUtil.GetExportType(exporterIFC, hostElement, out ifcEnumType);
                            switch (exportType)
                            {
                            case IFCExportType.ExportColumnType:
                                ifcPart = IFCInstanceExporter.CreateColumn(file, partGUID, ownerHistory, partName, partDescription, partObjectType,
                                                                           extrusionCreationData.GetLocalPlacement(), prodRep, partTag);
                                break;

                            case IFCExportType.ExportCovering:
                                IFCCoveringType coveringType = CeilingExporter.GetIFCCoveringType(hostElement, ifcEnumType);
                                ifcPart = IFCInstanceExporter.CreateCovering(file, partGUID, ownerHistory, partName, partDescription, partObjectType,
                                                                             extrusionCreationData.GetLocalPlacement(), prodRep, partTag, coveringType);
                                break;

                            case IFCExportType.ExportFooting:
                                IFCFootingType footingType = FootingExporter.GetIFCFootingType(hostElement, ifcEnumType);
                                ifcPart = IFCInstanceExporter.CreateFooting(file, partGUID, ownerHistory, partName, partDescription, partObjectType,
                                                                            extrusionCreationData.GetLocalPlacement(), prodRep, partTag, footingType);
                                break;

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

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

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

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

                        bool containedInLevel = (standaloneExport || asBuildingElement);
                        IFCPlacementSetter 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();
                }
            }
        }