Esempio n. 1
0
        /// <summary>
        /// Collects all solids and meshes within a GeometryElement; the solids which consist of multiple closed volumes
        /// will be split into single closed volume Solids.
        /// </summary>
        /// <remarks>
        /// Added in 2013 to replace the temporary API method ExporterIFCUtils.GetSplitClippedSolidMeshGeometry.
        /// </remarks>
        /// <param name="range">
        /// The upper and lower levels which act as the clipping boundaries.
        /// </param>
        /// <param name="geomElemToUse">The GeometryElement.</param>
        /// <returns>The collection of solids and meshes.</returns>
        public static SolidMeshGeometryInfo GetSplitClippedSolidMeshGeometry(GeometryElement geomElemToUse, IFCRange range)
        {
            SolidMeshGeometryInfo geometryInfo = GetClippedSolidMeshGeometry(geomElemToUse, range);

            geometryInfo.SplitSolidsList();
            return(geometryInfo);
        }
Esempio n. 2
0
        /// <summary>
        /// Collects all solids and meshes within a GeometryElement; the solids which consist of multiple closed volumes
        /// will be split into single closed volume Solids.
        /// </summary>
        /// <remarks>
        /// Added in 2013 to replace the temporary API method ExporterIFCUtils.GetSplitSolidMeshGeometry.
        /// </remarks>
        /// <param name="geomElemToUse">The GeometryElement.</param>
        /// <returns>The collection of solids and meshes.</returns>
        public static SolidMeshGeometryInfo GetSplitSolidMeshGeometry(GeometryElement geomElemToUse)
        {
            SolidMeshGeometryInfo geometryInfo = GetSolidMeshGeometry(geomElemToUse, Transform.Identity);

            geometryInfo.SplitSolidsList();
            return(geometryInfo);
        }
Esempio n. 3
0
        /// <summary>
        /// Collects all meshes within a GeometryElement and all solids clipped between a given IFCRange.
        /// </summary>
        /// <remarks>
        /// Added in 2013 to replace the temporary API method ExporterIFCUtils.GetClippedSolidMeshGeometry.
        /// </remarks>
        /// <param name="elem">
        /// The Element from which we can obtain a bounding box. Not handled directly in this method, it is used in an internal helper method.
        /// </param>
        /// <param name="geomElemToUse">
        /// The GeometryElement.
        /// </param>
        /// <param name="range">
        /// The upper and lower levels which act as the clipping boundaries.
        /// </param>
        /// <returns>The collection of solids and meshes.</returns>
        public static SolidMeshGeometryInfo GetClippedSolidMeshGeometry(GeometryElement geomElemToUse, IFCRange range)
        {
            SolidMeshGeometryInfo geometryInfo = GetSolidMeshGeometry(geomElemToUse, Transform.Identity);

            geometryInfo.ClipSolidsList(geomElemToUse, range);
            return(geometryInfo);
        }
Esempio n. 4
0
        /// <summary>
        /// Collects all solids and meshes within a GeometryElement.
        /// </summary>
        /// <remarks>
        /// Added in 2013 to replace the temporary API method ExporterIFCUtils.GetSolidMeshGeometry.
        /// </remarks>
        /// <param name="geomElemToUse">
        /// The GeometryElement.
        /// </param>
        /// <param name="trf">
        /// The initial Transform applied on the GeometryElement.
        /// </param>
        /// <returns>The collection of solids and meshes.</returns>
        public static SolidMeshGeometryInfo GetSolidMeshGeometry(GeometryElement geomElemToUse, Transform trf)
        {
            if (geomElemToUse == null)
            {
                throw new ArgumentNullException("geomElemToUse");
            }
            SolidMeshGeometryInfo geometryInfo = new SolidMeshGeometryInfo();

            // call to recursive helper method to obtain all solid and mesh geometry within geomElemToUse
            CollectSolidMeshGeometry(geomElemToUse, trf, geometryInfo);
            return(geometryInfo);
        }
Esempio n. 5
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);
        }
Esempio n. 6
0
        private static IFCAnyHandle FallbackTryToCreateAsExtrusion(ExporterIFC exporterIFC, Wall wallElement, SolidMeshGeometryInfo smCapsule,
            ElementId catId, Curve curve, Plane plane, double depth, IFCRange zSpan, IFCRange range, IFCPlacementSetter setter, 
            out IList<IFCExtrusionData> cutPairOpenings, out bool isCompletelyClipped)
        {
            cutPairOpenings = new List<IFCExtrusionData>();

            IFCAnyHandle bodyRep;
            isCompletelyClipped = false;

            XYZ localOrig = plane.Origin;

            bool hasExtrusion = HasElevationProfile(wallElement);
            if (hasExtrusion)
            {
                IList<CurveLoop> loops = GetElevationProfile(wallElement);
                if (loops.Count == 0)
                    hasExtrusion = false;
                else
                {
                    IList<IList<CurveLoop>> sortedLoops = ExporterIFCUtils.SortCurveLoops(loops);
                    if (sortedLoops.Count == 0)
                        return null;

                    // Current limitation: can't handle wall split into multiple disjointed pieces.
                    int numSortedLoops = sortedLoops.Count;
                    if (numSortedLoops > 1)
                        return null;

                    bool ignoreExtrusion = true;
                    bool cantHandle = false;
                    bool hasGeometry = false;
                    for (int ii = 0; (ii < numSortedLoops) && !cantHandle; ii++)
                    {
                        int sortedLoopSize = sortedLoops[ii].Count;
                        if (sortedLoopSize == 0)
                            continue;
                        if (!ExporterIFCUtils.IsCurveLoopConvexWithOpenings(sortedLoops[ii][0], wallElement, range, out ignoreExtrusion))
                        {
                            if (ignoreExtrusion)
                            {
                                // we need more information.  Is there something to export?  If so, we'll
                                // ignore the extrusion.  Otherwise, we will fail.

                                if (smCapsule.SolidsCount() == 0 && smCapsule.MeshesCount() == 0)
                                {
                                    continue;
                                }
                            }
                            else
                            {
                                cantHandle = true;
                            }
                            hasGeometry = true;
                        }
                        else
                        {
                            hasGeometry = true;
                        }
                    }

                    if (!hasGeometry)
                    {
                        isCompletelyClipped = true;
                        return null;
                    }

                    if (cantHandle)
                        return null;
                }
            }

            if (!CanExportWallGeometryAsExtrusion(wallElement, range))
                return null;

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

            // create extrusion boundary.
            IList<CurveLoop> boundaryLoops = new List<CurveLoop>();

            bool alwaysThickenCurve = IsWallBaseRectangular(wallElement, curve);

            if (!alwaysThickenCurve)
            {
                boundaryLoops = GetLoopsFromTopBottomFace(wallElement, exporterIFC);
                if (boundaryLoops.Count == 0)
                    return null;
            }
            else
            {
                CurveLoop newLoop = CurveLoop.CreateViaThicken(curve, wallElement.Width, XYZ.BasisZ);
                if (newLoop == null)
                    return null;

                if (!newLoop.IsCounterclockwise(XYZ.BasisZ))
                    newLoop = GeometryUtil.ReverseOrientation(newLoop);
                boundaryLoops.Add(newLoop);
            }

            // origin gets scaled later.
            XYZ setterOffset = new XYZ(0, 0, setter.Offset + (localOrig[2] - setter.BaseOffset));

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

            IFCAnyHandle bodyItemHnd = AddClippingsToBaseExtrusion(exporterIFC, wallElement,
               setterOffset, range, zSpan, baseBodyItemHnd, out cutPairOpenings);
            if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyItemHnd))
                return null;

            IFCAnyHandle styledItemHnd = BodyExporter.CreateSurfaceStyleForRepItem(exporterIFC, wallElement.Document,
                baseBodyItemHnd, ElementId.InvalidElementId);

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

            IFCAnyHandle contextOfItemsBody = exporterIFC.Get3DContextHandle("Body");
            if (baseBodyItemHnd.Id == bodyItemHnd.Id)
            {
                bodyRep = RepresentationUtil.CreateSweptSolidRep(exporterIFC, wallElement, catId, contextOfItemsBody, bodyItems, null);
            }
            else
            {
                bodyRep = RepresentationUtil.CreateClippingRep(exporterIFC, wallElement, catId, contextOfItemsBody, bodyItems);
            }

            return bodyRep;
        }
 /// <summary>
 /// Collects all solids and meshes within all nested levels of a given GeometryElement.
 /// </summary>
 /// <remarks>
 /// This is a private helper method for the GetSolidMeshGeometry type collection methods.
 /// </remarks>
 /// <param name="geomElem">The GeometryElement we are collecting solids and meshes from.</param>
 /// <param name="trf">The initial Transform applied on the GeometryElement.</param>
 /// <param name="solidMeshCapsule">The SolidMeshGeometryInfo object that contains the lists of collected solids and meshes.</param>
 private static void CollectSolidMeshGeometry(GeometryElement geomElem, Transform trf, SolidMeshGeometryInfo solidMeshCapsule)
 {
     if (geomElem == null)
         return;
     
     GeometryElement currGeomElem = geomElem;
     Transform localTrf = trf;
     if (localTrf == null)
         localTrf = Transform.Identity;
     else if (!localTrf.IsIdentity)
         currGeomElem = GetTransformedGeometry(geomElem, localTrf);
     
     // iterate through the GeometryObjects contained in the GeometryElement
     foreach (GeometryObject geomObj in currGeomElem)
     {
         Solid solid = geomObj as Solid;
         if (solid != null && solid.Faces.Size > 0 && solid.Volume > 0.0)
         {
             solidMeshCapsule.AddSolid(solid);
         }
         else
         {
             Mesh mesh = geomObj as Mesh;
             if (mesh != null)
             {
                 solidMeshCapsule.AddMesh(mesh);
             }
             else
             {
                 // if the current geomObj is castable as a GeometryInstance, then we perform the same collection on its symbol geometry
                 GeometryInstance inst = geomObj as GeometryInstance;
                 if (inst != null)
                 {
                     GeometryElement instanceSymbol = inst.GetSymbolGeometry();
                     if (instanceSymbol != null)
                     {
                         Transform instanceTransform = localTrf.Multiply(inst.Transform);
                         CollectSolidMeshGeometry(instanceSymbol, instanceTransform, solidMeshCapsule);
                     }
                 }
             }
         }
     }
 }
 /// <summary>
 /// Collects all solids and meshes within a GeometryElement.
 /// </summary>
 /// <remarks>
 /// Added in 2013 to replace the temporary API method ExporterIFCUtils.GetSolidMeshGeometry.
 /// </remarks>
 /// <param name="geomElemToUse">The GeometryElement.</param>
 /// <param name="trf">The initial Transform applied on the GeometryElement.</param>
 /// <returns>The collection of solids and meshes.</returns>
 public static SolidMeshGeometryInfo GetSolidMeshGeometry(GeometryElement geomElemToUse, Transform trf)
 {
     if (geomElemToUse == null)
     {
         throw new ArgumentNullException("geomElemToUse");
     }
     SolidMeshGeometryInfo geometryInfo = new SolidMeshGeometryInfo();
     // call to recursive helper method to obtain all solid and mesh geometry within geomElemToUse
     CollectSolidMeshGeometry(geomElemToUse, trf, geometryInfo);
     return geometryInfo;
 }
Esempio n. 9
0
 /// <summary>
 /// Collects all solids and meshes within all nested levels of a given GeometryElement.
 /// </summary>
 /// <remarks>
 /// This is a private helper method for the GetSolidMeshGeometry type collection methods.
 /// </remarks>
 /// <param name="geomElem">
 /// The GeometryElement we are collecting solids and meshes from.
 /// </param>
 /// <param name="trf">
 /// The initial Transform applied on the GeometryElement.
 /// </param>
 /// <param name="solidMeshCapsule">
 /// The SolidMeshGeometryInfo object that contains the lists of collected solids and meshes.
 /// </param>
 private static void CollectSolidMeshGeometry(GeometryElement geomElem, Transform trf, SolidMeshGeometryInfo solidMeshCapsule)
 {
     if (geomElem == null)
     {
         return;
     }
     GeometryElement currGeomElem = geomElem;
     Transform localTrf = trf;
     if (localTrf == null)
     {
         localTrf = Transform.Identity;
     }
     else if (!localTrf.IsIdentity)
     {
         currGeomElem = geomElem.GetTransformed(localTrf);
         // The geometry element created by "GetTransformed" is a copy which will have its own allocated
         // membership - this needs to be stored and disposed of (see AllocatedGeometryObjectCache
         // for details)
         ExporterCacheManager.AllocatedGeometryObjectCache.AddGeometryObject(currGeomElem);
     }
     // iterate through the GeometryObjects contained in the GeometryElement
     foreach (GeometryObject geomObj in currGeomElem){
         Solid solid = geomObj as Solid;
         if (solid != null && solid.Faces.Size > 0 && solid.Volume > 0.0)
         {
             solidMeshCapsule.AddSolid(solid);
         }
         else
         {
             Mesh mesh = geomObj as Mesh;
             if (mesh != null)
             {
                 solidMeshCapsule.AddMesh(mesh);
             }
             else
             {
                 // if the current geomObj is castable as a GeometryInstance, then we perform the same collection on its symbol geometry
                 GeometryInstance inst = geomObj as GeometryInstance;
                 if (inst != null)
                 {
                     GeometryElement instanceSymbol = inst.GetSymbolGeometry();
                     if (instanceSymbol != null)
                     {
                         Transform instanceTransform = localTrf.Multiply(inst.Transform);
                         CollectSolidMeshGeometry(instanceSymbol, instanceTransform, solidMeshCapsule);
                     }
                 }
             }
         }
     }
 }
Esempio n. 10
0
        /// <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));
        }
Esempio n. 11
0
        /// <summary>
        /// Collects all solids and meshes within all nested levels of a given GeometryElement.
        /// </summary>
        /// <remarks>
        /// This is a private helper method for the GetSolidMeshGeometry type collection methods.
        /// </remarks>
        /// <param name="geomElem">
        /// The GeometryElement we are collecting solids and meshes from.
        /// </param>
        /// <param name="trf">
        /// The initial Transform applied on the GeometryElement.
        /// </param>
        /// <param name="solidMeshCapsule">
        /// The SolidMeshGeometryInfo object that contains the lists of collected solids and meshes.
        /// </param>
        private static void CollectSolidMeshGeometry(GeometryElement geomElem, Transform trf, SolidMeshGeometryInfo solidMeshCapsule)
        {
            if (geomElem == null)
            {
                return;
            }
            GeometryElement currGeomElem = geomElem;
            Transform       localTrf     = trf;

            if (localTrf == null)
            {
                localTrf = Transform.Identity;
            }
            else if (!localTrf.IsIdentity)
            {
                currGeomElem = geomElem.GetTransformed(localTrf);
                // The geometry element created by "GetTransformed" is a copy which will have its own allocated
                // membership - this needs to be stored and disposed of (see AllocatedGeometryObjectCache
                // for details)
                ExporterCacheManager.AllocatedGeometryObjectCache.AddGeometryObject(currGeomElem);
            }
            // iterate through the GeometryObjects contained in the GeometryElement
            foreach (GeometryObject geomObj in currGeomElem)
            {
                Solid solid = geomObj as Solid;
                if (solid != null && solid.Faces.Size > 0 && solid.Volume > 0.0)
                {
                    solidMeshCapsule.AddSolid(solid);
                }
                else
                {
                    Mesh mesh = geomObj as Mesh;
                    if (mesh != null)
                    {
                        solidMeshCapsule.AddMesh(mesh);
                    }
                    else
                    {
                        // if the current geomObj is castable as a GeometryInstance, then we perform the same collection on its symbol geometry
                        GeometryInstance inst = geomObj as GeometryInstance;
                        if (inst != null)
                        {
                            GeometryElement instanceSymbol = inst.GetSymbolGeometry();
                            if (instanceSymbol != null)
                            {
                                Transform instanceTransform = localTrf.Multiply(inst.Transform);
                                CollectSolidMeshGeometry(instanceSymbol, instanceTransform, solidMeshCapsule);
                            }
                        }
                    }
                }
            }
        }