public double GetOpeningArea(
            Wall elemHost,
            Element elemInsert,
            Room room,
            Solid roomSolid)
        {
            Document doc         = room.Document;
            double   openingArea = 0;

            if (elemInsert is FamilyInstance)
            {
                FamilyInstance fi = elemInsert as FamilyInstance;

                if (IsInRoom(room, fi))
                {
                    if (elemHost is Wall)
                    {
                        Wall wall = elemHost as Wall;
                        openingArea = GetWallCutArea(fi, wall);
                    }

                    //if( openingArea.Equals( 0 ) )
                    //{
                    //  openingArea = GetDoorWinAreaFromParameter( doc, fi );
                    //}
                }
            }

            if (elemInsert is Wall)
            {
                SolidHandler solidHandler = new SolidHandler();
                openingArea = solidHandler.GetWallAsOpeningArea(
                    elemInsert, roomSolid);
            }
            return(openingArea);
        }
        public double GetWallCutArea(
            FamilyInstance fi,
            Wall wall)
        {
            Document doc = fi.Document;

            XYZ cutDir = null;

            CurveLoop curveLoop
                = ExporterIFCUtils.GetInstanceCutoutFromWall(
                      fi.Document, wall, fi, out cutDir);

            IList <CurveLoop> loops = new List <CurveLoop>(1);

            loops.Add(curveLoop);

            if (!wall.IsStackedWallMember)
            {
                return(ExporterIFCUtils.ComputeAreaOfCurveLoops(loops));
            }
            else
            {
                // Will not get multiple stacked walls with
                // varying thickness due to the nature of rooms.
                // Use ReferenceIntersector if we can identify
                // those missing room faces...open for suggestions.

                SolidHandler solHandler = new SolidHandler();
                Options      optCompRef
                    = doc.Application.Create.NewGeometryOptions();
                if (null != optCompRef)
                {
                    optCompRef.ComputeReferences = true;
                    optCompRef.DetailLevel       = ViewDetailLevel.Medium;
                }

                GeometryElement geomElemHost
                    = wall.get_Geometry(optCompRef)
                      as GeometryElement;

                Solid solidOpening = GeometryCreationUtilities
                                     .CreateExtrusionGeometry(loops,
                                                              cutDir.Negate(), .1);

                Solid solidHost
                    = solHandler.CreateSolidFromBoundingBox(
                          null, geomElemHost.GetBoundingBox(), null);

                // We dont really care about the boundingbox
                // rotation as we only need the intersected solid.

                if (solidHost == null)
                {
                    return(0);
                }

                Solid intersectSolid = BooleanOperationsUtils
                                       .ExecuteBooleanOperation(solidOpening,
                                                                solidHost, BooleanOperationsType.Intersect);

                if (intersectSolid.Faces.Size.Equals(0))
                {
                    solidOpening = GeometryCreationUtilities
                                   .CreateExtrusionGeometry(loops, cutDir, .1);

                    intersectSolid = BooleanOperationsUtils
                                     .ExecuteBooleanOperation(solidOpening,
                                                              solidHost, BooleanOperationsType.Intersect);
                }

                if (DebugHandler.EnableSolidUtilityVolumes)
                {
                    using (Transaction t = new Transaction(doc))
                    {
                        t.Start("Stacked1");
                        ShapeCreator.CreateDirectShape(doc,
                                                       intersectSolid, "stackedOpening");
                        t.Commit();
                    }
                }
                return(solHandler.GetLargestFaceArea(
                           intersectSolid));
            }
        }