Ejemplo n.º 1
0
        /***************************************************/
        /****              Private Methods              ****/
        /***************************************************/

        private static Dictionary <PlanarSurface, List <PlanarSurface> > PanelSurfaces_HostDocument(this HostObject hostObject, IEnumerable <ElementId> insertsToIgnore = null, RevitSettings settings = null)
        {
            List <Autodesk.Revit.DB.Plane> planes = hostObject.IPanelPlanes();

            if (planes.Count == 0)
            {
                return(null);
            }

            Document doc = hostObject.Document;
            Dictionary <PlanarSurface, List <PlanarSurface> > result = new Dictionary <PlanarSurface, List <PlanarSurface> >();

            IList <ElementId> inserts = hostObject.FindInserts(true, true, true, true);

            if (insertsToIgnore != null)
            {
                inserts = inserts.Where(x => insertsToIgnore.All(y => x.IntegerValue != y.IntegerValue)).ToList();
            }

            Transaction            t = new Transaction(doc);
            FailureHandlingOptions failureHandlingOptions = t.GetFailureHandlingOptions().SetClearAfterRollback(true);

            t.Start("Temp Delete Inserts And Unjoin Geometry");

            try
            {
                foreach (ElementId id in JoinGeometryUtils.GetJoinedElements(doc, hostObject))
                {
                    JoinGeometryUtils.UnjoinGeometry(doc, hostObject, doc.GetElement(id));
                }

                if (hostObject is Wall)
                {
                    WallUtils.DisallowWallJoinAtEnd((Wall)hostObject, 0);
                    WallUtils.DisallowWallJoinAtEnd((Wall)hostObject, 1);
                }

                if (insertsToIgnore != null)
                {
                    doc.Delete(insertsToIgnore.ToList());
                }

                doc.Regenerate();

                List <Solid> solidsWithOpenings = hostObject.Solids(new Options());
                List <Solid> fullSolids;

                if (inserts.Count != 0)
                {
                    solidsWithOpenings = solidsWithOpenings.Select(x => SolidUtils.Clone(x)).ToList();

                    doc.Delete(inserts);
                    doc.Regenerate();

                    fullSolids = hostObject.Solids(new Options());
                }
                else
                {
                    fullSolids = solidsWithOpenings;
                }

                fullSolids = fullSolids.SelectMany(x => SolidUtils.SplitVolumes(x)).ToList();
                if (hostObject is Wall)
                {
                    fullSolids.ForEach(x => BooleanOperationsUtils.CutWithHalfSpaceModifyingOriginalSolid(x, planes[0]));
                    Autodesk.Revit.DB.Plane flippedPlane = Autodesk.Revit.DB.Plane.CreateByNormalAndOrigin(-planes[0].Normal, planes[0].Origin + planes[0].Normal * 1e-3);
                    fullSolids.ForEach(x => BooleanOperationsUtils.CutWithHalfSpaceModifyingOriginalSolid(x, flippedPlane));
                    fullSolids = fullSolids.SelectMany(x => SolidUtils.SplitVolumes(x)).ToList();
                    planes[0]  = Autodesk.Revit.DB.Plane.CreateByNormalAndOrigin(-planes[0].Normal, planes[0].Origin);
                }


                foreach (Autodesk.Revit.DB.Plane plane in planes)
                {
                    foreach (Solid s in fullSolids)
                    {
                        List <CurveLoop> loops = new List <CurveLoop>();
                        foreach (Autodesk.Revit.DB.Face f in s.Faces)
                        {
                            PlanarFace pf = f as PlanarFace;
                            if (pf == null)
                            {
                                continue;
                            }

                            if (Math.Abs(1 - pf.FaceNormal.DotProduct(plane.Normal)) <= settings.DistanceTolerance && Math.Abs((pf.Origin - plane.Origin).DotProduct(plane.Normal)) <= settings.AngleTolerance)
                            {
                                loops.AddRange(pf.GetEdgesAsCurveLoops());
                            }
                        }

                        CurveLoop            outline  = loops.FirstOrDefault(x => x.IsCounterclockwise(plane.Normal));
                        PlanarSurface        surface  = new PlanarSurface(outline.FromRevit(), null);
                        List <PlanarSurface> openings = new List <PlanarSurface>();
                        foreach (CurveLoop loop in loops.Where(x => x != outline))
                        {
                            openings.Add(new PlanarSurface(loop.FromRevit(), null));
                        }

                        if (inserts.Count != 0)
                        {
                            List <Solid> openingVolumes = new List <Solid>();
                            foreach (Solid s2 in solidsWithOpenings)
                            {
                                openingVolumes.Add(BooleanOperationsUtils.ExecuteBooleanOperation(s, s2, BooleanOperationsType.Difference));
                            }

                            foreach (Solid s2 in openingVolumes)
                            {
                                foreach (Autodesk.Revit.DB.Face f in s2.Faces)
                                {
                                    PlanarFace pf = f as PlanarFace;
                                    if (pf == null)
                                    {
                                        continue;
                                    }

                                    if (Math.Abs(1 - pf.FaceNormal.DotProduct(plane.Normal)) <= settings.DistanceTolerance && Math.Abs((pf.Origin - plane.Origin).DotProduct(plane.Normal)) <= settings.AngleTolerance)
                                    {
                                        foreach (CurveLoop cl in pf.GetEdgesAsCurveLoops())
                                        {
                                            openings.Add(new PlanarSurface(cl.FromRevit(), null));
                                        }
                                    }
                                }
                            }
                        }

                        result.Add(surface, openings);
                    }
                }
            }
            catch
            {
                BH.Engine.Reflection.Compute.RecordError(String.Format("Geometrical processing of a Revit element failed due to an internal Revit error. Converted panel might be missing one or more of its surfaces. Revit ElementId: {0}", hostObject.Id));
            }

            t.RollBack(failureHandlingOptions);

            return(result);
        }