public static SolidIntersection HasIntersection(this Solid solid0, Solid solid1, out Solid result)
 {
     result = null;
     try
     {
         result = BooleanOperationsUtils.ExecuteBooleanOperation(solid0, solid1, BooleanOperationsType.Intersect);
         if (Math.Abs(result.Volume) > 0.000001)
         {
             // Intersecting.
             return(SolidIntersection.Intersecting);
         }
         result = BooleanOperationsUtils.ExecuteBooleanOperation
                      (solid0, solid1, BooleanOperationsType.Union);
         double dArea = Math.Abs(solid0.SurfaceArea + solid1.SurfaceArea - result.SurfaceArea);
         if (dArea < 0.00001 && solid0.Edges.Size + solid1.Edges.Size == result.Edges.Size)
         {
             // Neither intersecting, nor touching.
             return(SolidIntersection.NonIntersecting);
         }
         else
         {
             // Touching.
             return(SolidIntersection.Touching);
         }
     }
     catch (Autodesk.Revit.Exceptions.InvalidOperationException)
     {
         return(SolidIntersection.Invalid);
     }
 }
        public static IEnumerable <ElementId> CastSphere(
            ModelInfo info, IEnumerable <XYZ> pts, double radius,
            BuiltInCategory bic = BuiltInCategory.INVALID, View view = null)
        {
            if (!pts.Any())
            {
                return(new List <ElementId>());
            }

            var solids = new Queue <Solid>();

            foreach (var pt in pts)
            {
                solids.Enqueue(CreateSphereAt(pt, radius));
            }

            var union_solid = solids.Dequeue();

            while (solids.Any())
            {
                var other = solids.Dequeue();
                union_solid = BooleanOperationsUtils.ExecuteBooleanOperation(union_solid, other, BooleanOperationsType.Union);
            }

            ElementIntersectsSolidFilter intersectSphere = new ElementIntersectsSolidFilter(union_solid);
            FilteredElementCollector     coll;

            coll = view != null ? new FilteredElementCollector(info.DOC, view.Id) : new FilteredElementCollector(info.DOC);

            var intersection = bic == BuiltInCategory.INVALID ?
                               coll.WherePasses(intersectSphere).ToElementIds() :
                               coll.WherePasses(intersectSphere).OfCategory(bic).ToElementIds();

            return(intersection);
        }
        public Solid Unionsolid(List <Solid> solids)
        {
            List <Solid> MB = new List <Solid> {
                solids[1], solids[2]
            };
            Solid result = null;

            foreach (Solid item in solids)
            {
                if (result == null)
                {
                    result = item;
                }
                else
                {
                    try
                    {
                        var t = BooleanOperationsUtils.ExecuteBooleanOperation(result, item, BooleanOperationsType.Intersect);
                        if (t.Volume != 0)
                        {
                            result = BooleanOperationsUtils.ExecuteBooleanOperation(result, item, BooleanOperationsType.Union);
                        }
                    }
                    catch
                    {
                    }
                }
            }
            return(result);
        }
示例#4
0
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            Document doc = commandData.Application.ActiveUIDocument.Document;

            Solid box    = Box();
            Solid sphere = Sphere();

            Solid unionSolid     = BooleanOperationsUtils.ExecuteBooleanOperation(box, sphere, BooleanOperationsType.Union);
            Solid intersectSolid = BooleanOperationsUtils.ExecuteBooleanOperation(box, sphere, BooleanOperationsType.Intersect);
            Solid diffSolid      = BooleanOperationsUtils.ExecuteBooleanOperation(box, sphere, BooleanOperationsType.Difference);

            //Use DirectShape to visualise geometries
            using (Transaction t = new Transaction(doc, "Transaction"))
            {
                t.Start();
                GeometryObject[] unionGeomObj = new GeometryObject[] { unionSolid };
                GeometryObject[] interGeomObj = new GeometryObject[] { intersectSolid };
                GeometryObject[] diffGeomObj  = new GeometryObject[] { diffSolid };
                DirectShape      ds1          = DirectShape.CreateElement(doc, new ElementId(BuiltInCategory.OST_GenericModel));
                ds1.SetShape(unionGeomObj);
                DirectShape ds2 = DirectShape.CreateElement(doc, new ElementId(BuiltInCategory.OST_GenericModel));
                ds2.SetShape(interGeomObj);
                DirectShape ds3 = DirectShape.CreateElement(doc, new ElementId(BuiltInCategory.OST_GenericModel));
                ds3.SetShape(diffGeomObj);
                t.Commit();
            }

            return(Result.Succeeded);
        }
示例#5
0
        private Solid GetSolid(GeometryElement geoElement)
        {
            Solid unionSolid = null;

            try
            {
                Options opt = m_app.Application.Create.NewGeometryOptions();
                opt.ComputeReferences = true;
                opt.DetailLevel       = Autodesk.Revit.DB.ViewDetailLevel.Fine;

                foreach (GeometryObject obj in geoElement)
                {
                    Solid solid = obj as Solid;
                    if (null != solid)
                    {
                        if (solid.Volume > 0)
                        {
                            if (unionSolid == null)
                            {
                                unionSolid = solid;
                            }
                            else
                            {
                                unionSolid = BooleanOperationsUtils.ExecuteBooleanOperation(unionSolid, solid, BooleanOperationsType.Union);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Failed to get solid.\n" + ex.Message, "Get Solid", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
            return(unionSolid);
        }
示例#6
0
        public static double GetIntersectedSolidArea(
            Document host,
            Solid hostElement,
            RevitLinkInstance rins,
            Solid linkedElement)
        {
            // Step 1 "Determine the transformation T from the linked document Q coordinates to P's."

            Transform transForm = rins.GetTransform();

            // Step 2 "Open the linked project Q and retrieve the solid Sb of B."

            // linkedElement is Solid of linked Link

            // Step 3 "Transform it to P's coordinate space: T * Sb."

            Solid tmp = SolidUtils.CreateTransformed(linkedElement, transForm);

            // Step 4 "Retrieve the solid Sa of A"
            // hostElement is hostElementSolid

            Solid result = BooleanOperationsUtils.ExecuteBooleanOperation(
                hostElement, tmp, BooleanOperationsType.Intersect);


            return(result.SurfaceArea);
        }
示例#7
0
        /// <summary>
        /// Execute a Boolean operation, and catch the exception.
        /// </summary>
        /// <param name="id">The id of the object demanding the Boolean operation.</param>
        /// <param name="secondId">The id of the object providing the second solid.</param>
        /// <param name="firstSolid">The first solid parameter to ExecuteBooleanOperation.</param>
        /// <param name="secondSolid">The second solid parameter to ExecuteBooleanOperation.</param>
        /// <param name="opType">The Boolean operation type.</param>
        /// <param name="suggestedShiftDirection">If the Boolean operation fails, a unit vector used to retry with a small shift.  Can be null.</param>
        /// <returns>The result of the Boolean operation, or the first solid if the operation fails.</returns>
        public static Solid ExecuteSafeBooleanOperation(int id, int secondId, Solid firstSolid, Solid secondSolid, BooleanOperationsType opType, XYZ suggestedShiftDirection)
        {
            // Perform default operations if one of the arguments is null.
            if (firstSolid == null || secondSolid == null)
            {
                if (firstSolid == null && secondSolid == null)
                {
                    return(null);
                }

                switch (opType)
                {
                case BooleanOperationsType.Union:
                {
                    if (firstSolid == null)
                    {
                        return(secondSolid);
                    }

                    return(firstSolid);
                }

                case BooleanOperationsType.Difference:
                {
                    if (firstSolid == null)
                    {
                        return(null);
                    }

                    return(firstSolid);
                }

                default:
                    // for .Intersect
                    return(null);
                }
            }

            Solid resultSolid = null;

            try
            {
                Solid secondOperand = secondSolid;
                resultSolid = BooleanOperationsUtils.ExecuteBooleanOperation(firstSolid, secondOperand, opType);
            }
            catch (Exception ex)
            {
                Importer.TheLog.LogError(id, ex.Message, false);
                resultSolid = firstSolid;
            }

            if (SolidValidator.IsValidGeometry(resultSolid))
            {
                return(resultSolid);
            }

            Importer.TheLog.LogError(id, opType.ToString() + " operation failed with void from #" + secondId.ToString(), false);
            return(firstSolid);
        }
        public static bool CheckSolidsIsIntersect(Solid solid1, Solid solid2)
        {
            Solid  interSolid = BooleanOperationsUtils.ExecuteBooleanOperation(solid1, solid2, BooleanOperationsType.Intersect);
            double volume     = Math.Abs(interSolid.Volume);

            if (volume > 0.000001)
            {
                return(true);
            }
            return(false);
        }
示例#9
0
        /// <summary>
        /// Execute a Boolean operation, and catch the exception.
        /// </summary>
        /// <param name="id">The id of the object demanding the Boolean operation.</param>
        /// <param name="secondId">The id of the object providing the second solid.</param>
        /// <param name="firstSolid">The first solid parameter to ExecuteBooleanOperation.</param>
        /// <param name="secondSolid">The second solid parameter to ExecuteBooleanOperation.</param>
        /// <param name="opType">The Boolean operation type.</param>
        /// <returns>The result of the Boolean operation, or the first solid if the operation fails.</returns>
        public static Solid ExecuteSafeBooleanOperation(int id, int secondId, Solid firstSolid, Solid secondSolid, BooleanOperationsType opType)
        {
            if (firstSolid == null || secondSolid == null)
            {
                if (firstSolid == null && secondSolid == null)
                {
                    return(null);
                }

                if (opType == BooleanOperationsType.Union)
                {
                    if (firstSolid == null)
                    {
                        return(secondSolid);
                    }

                    return(firstSolid);
                }

                if (opType == BooleanOperationsType.Difference)
                {
                    if (firstSolid == null)
                    {
                        return(null);
                    }

                    return(firstSolid);
                }

                // for .Intersect
                return(null);
            }

            Solid resultSolid = null;

            try
            {
                resultSolid = BooleanOperationsUtils.ExecuteBooleanOperation(firstSolid, secondSolid, opType);
            }
            catch (Exception ex)
            {
                IFCImportFile.TheLog.LogError(id, ex.Message, false);
                resultSolid = firstSolid;
            }

            if (SolidValidator.IsValidGeometry(resultSolid))
            {
                return(resultSolid);
            }

            IFCImportFile.TheLog.LogError(id, opType.ToString() + " operation failed with void from #" + secondId.ToString(), false);
            return(firstSolid);
        }
示例#10
0
        static Solid GetResultingSolid(Solid solid, IList <Solid> solids)
        {
            Solid resultingSolid = solid;

            foreach (Solid currSolid in solids)
            {
                resultingSolid = BooleanOperationsUtils
                                 .ExecuteBooleanOperation(resultingSolid, currSolid,
                                                          BooleanOperationsType.Difference);
            }

            return(resultingSolid);
        }
示例#11
0
        /// <summary>
        /// Gets the result of between a solid and a solid cross.
        /// </summary>
        /// <param name="solid1"></param>
        /// <param name="solid2"></param>
        /// <returns></returns>
        public static bool CrossSolid(this Solid solid1, Solid solid2)
        {
            if (solid1 == null)
            {
                throw new ArgumentNullException(nameof(solid1));
            }

            if (solid2 == null)
            {
                throw new ArgumentNullException(nameof(solid2));
            }

            return(BooleanOperationsUtils.ExecuteBooleanOperation(solid1, solid2, BooleanOperationsType.Intersect).Volume > 0);
        }
示例#12
0
        public Solid MergeSolids(Solid solid1, Solid solid2)
        {
            var result = default(Solid);

            try
            {
                result = BooleanOperationsUtils.ExecuteBooleanOperation(solid1, solid2, BooleanOperationsType.Union);
            }
            catch (Exception e)
            {
                result = null;
            }
            return(result);
        }
示例#13
0
        static public Solid Clone(/*this*/ Solid solid)
        {
            if (solid == null)
            {
                return(null);
            }

            // Better than unioning the solid with itself:
            // use a small cube contained within the original
            // solid instead, e.g. a 1x1x1 cube at the origin
            // or something.

            return(BooleanOperationsUtils
                   .ExecuteBooleanOperation(solid, solid,
                                            BooleanOperationsType.Union));
        }
示例#14
0
        /// <summary>
        /// 获取楼梯合并solid
        /// </summary>
        /// <param name="e"></param>
        /// <returns></returns>
        public static Solid AllUnionSolid(Element e)
        {
            Solid sd = null;

            try
            {
                Options options = new Options();
                options.IncludeNonVisibleObjects = false;
                options.DetailLevel       = ViewDetailLevel.Fine;
                options.ComputeReferences = true;

                GeometryElement geoElement1 = e.get_Geometry(options);//点进去
                IEnumerator     enumerator  = geoElement1.GetEnumerator();
                {
                    while (enumerator.MoveNext())
                    {
                        GeometryObject gobj = enumerator.Current as GeometryObject;
                        if (gobj is GeometryInstance)
                        {
                            GeometryInstance geoInstance = gobj as GeometryInstance;
                            GeometryElement  gElem       = geoInstance.SymbolGeometry;
                            IEnumerator      enumerator1 = gElem.GetEnumerator();
                            while (enumerator1.MoveNext())
                            {
                                GeometryObject gobj1 = enumerator1.Current as GeometryObject;
                                if (gobj1 is Solid)
                                {
                                    Solid solid = gobj1 as Solid;
                                    if (sd == null)
                                    {
                                        sd = solid;
                                    }
                                    else
                                    {
                                        sd = BooleanOperationsUtils.ExecuteBooleanOperation(sd, solid, BooleanOperationsType.Union);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch
            { }
            return(sd);
        }
示例#15
0
        public bool CheckSolid(Solid solid1, Solid solid2)
        {
            bool flag = false;

            try
            {
                Solid solid = BooleanOperationsUtils.ExecuteBooleanOperation(solid1, solid2, BooleanOperationsType.Intersect);
                if (solid.Volume > 0.000000001)
                {
                    flag = true;
                }
                return(flag);
            }
            catch
            {
                return(flag);
            }
        }
示例#16
0
        public Result Execute(
            ExternalCommandData commandData,
            ref string message,
            ElementSet elements)
        {
            UIApplication app   = commandData.Application;
            UIDocument    uidoc = app.ActiveUIDocument;
            Document      doc   = uidoc.Document;

            // Execute the BrepBuilder methods.

            BRepBuilder brepBuilderSolid = CreateBrepSolid();
            BRepBuilder brepBuilderVoid  = CreateBrepVoid();

            Solid cube     = brepBuilderSolid.GetResult();
            Solid cylinder = brepBuilderVoid.GetResult();

            // Determine their Boolean difference.

            Solid difference
                = BooleanOperationsUtils.ExecuteBooleanOperation(
                      cube, cylinder, BooleanOperationsType.Difference);

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

            list.Add(difference);

            using (Transaction tr = new Transaction(doc))
            {
                tr.Start("Create a DirectShape");

                // Create a direct shape.

                DirectShape ds = DirectShape.CreateElement(doc,
                                                           new ElementId(BuiltInCategory.OST_GenericModel));

                ds.SetShape(list);

                tr.Commit();
            }
            return(Result.Succeeded);
        }
示例#17
0
        /// <summary>
        /// возвращаетд долю от соллда
        /// </summary>
        /// <param name="room"></param>
        /// <param name="el"></param>
        /// <returns></returns>
        private double GetPart(Room room, Element el)
        {
            List <Solid> roomSolids    = (new GetGeometry(room)).Solids;
            List <Solid> elementSolids = (new GetGeometry(el)).Solids;
            double       old_part      = 1000000.0;

            foreach (var roomSolid in roomSolids)
            {
                foreach (var elementSolid in elementSolids)
                {
                    Solid  new_solid = BooleanOperationsUtils.ExecuteBooleanOperation(roomSolid, elementSolid, BooleanOperationsType.Union);
                    double new_part  = Math.Round(new_solid.Volume - (roomSolid.Volume + elementSolid.Volume) + new_solid.SurfaceArea - (roomSolid.SurfaceArea + elementSolid.SurfaceArea), 10);
                    if (new_part < old_part)
                    {
                        old_part = new_part;
                    }
                }
            }
            return(old_part);
        }
示例#18
0
        static internal XYZ IntersectPointBetweenBeamAndColumn(Element targetBeam, Element targetColumn)
        {
            FamilyInstance beamInstance   = targetBeam as FamilyInstance;
            FamilyInstance columnInstance = targetColumn as FamilyInstance;

            // The beam and the column could have more than one solid modeled on the family
            // We will querry both and search for the solid that has more volume (main solid)
            Solid mainBeamSolid   = GetMainSolid(beamInstance);
            Solid mainColumnSolid = GetMainSolid(columnInstance);

            Solid intersectingSolid = null;
            XYZ   intersectingPoint = null;

            intersectingSolid = BooleanOperationsUtils.ExecuteBooleanOperation(mainBeamSolid, mainColumnSolid, BooleanOperationsType.Intersect);

            if (intersectingSolid != null)
            {
                intersectingPoint = intersectingSolid.ComputeCentroid();
            }

            return(intersectingPoint);
        }
示例#19
0
        /// <summary>
        /// Основная проверка пересечения солидов
        /// </summary>
        /// <param name="room">комната</param>
        /// <param name="el">елемент</param>
        /// <returns></returns>
        private bool IsIntersection(Room room, Element el)
        {
            List <Solid> roomSolids    = (new GetGeometry(room)).Solids;
            List <Solid> elementSolids = (new GetGeometry(el)).Solids;

            foreach (var roomSolid in roomSolids)
            {
                foreach (var elementSolid in elementSolids)
                {
                    Solid new_solid = BooleanOperationsUtils.ExecuteBooleanOperation(roomSolid, elementSolid, BooleanOperationsType.Union);
                    if (Math.Round((new_solid.Volume - roomSolid.Volume - elementSolid.Volume + new_solid.SurfaceArea - roomSolid.SurfaceArea - elementSolid.SurfaceArea), 11) != 0)
                    {
                        return(true);
                    }
                }
            }
            return(false);

            //else
            //{
            //    foreach (var roomSolid in roomSolids)
            //    {
            //        foreach (var elementSolid in elementSolids)
            //        {
            //            Solid new_solid = BooleanOperationsUtils.ExecuteBooleanOperation(roomSolid, elementSolid, BooleanOperationsType.Union);
            //            if (Math.Round((new_solid.SurfaceArea -
            //                (roomSolid.SurfaceArea + elementSolid.SurfaceArea)), 10) != 0)
            //            {
            //                return true;
            //            }

            //        }
            //    }
            //    return false;
            //}
        }
示例#20
0
        public Result Execute(
            ExternalCommandData commandData,
            ref string message,
            ElementSet elements)
        {
            UIApplication uiapp = commandData.Application;
            UIDocument    uidoc = uiapp.ActiveUIDocument;
            Application   app   = uiapp.Application;
            Document      doc   = uidoc.Document;
            Selection     sel   = uidoc.Selection;

            // Retrieve all floors from the model

            var floors
                = new FilteredElementCollector(doc)
                  .OfClass(typeof(Floor))
                  .ToElements()
                  .Cast <Floor>()
                  .ToList();

            if (2 != floors.Count)
            {
                message = "Please create two intersected floors";
                return(Result.Failed);
            }

            // Retrieve the floor solids

            Options opt = new Options();

            var geometry1 = floors[0].get_Geometry(opt);
            var geometry2 = floors[1].get_Geometry(opt);

            var solid1 = geometry1.FirstOrDefault() as Solid;
            var solid2 = geometry2.FirstOrDefault() as Solid;

            // Calculate the intersection solid

            var intersectedSolid = BooleanOperationsUtils
                                   .ExecuteBooleanOperation(solid1, solid2,
                                                            BooleanOperationsType.Intersect);

            // Search for the metric mass family template file

            string template_path = DirSearch(
                app.FamilyTemplatePath,
                "Metric Mass.rft");

            // Create a new temporary family

            var family_doc = app.NewFamilyDocument(
                template_path);

            // Create a free form element
            // from the intersection solid

            using (var t = new Transaction(family_doc))
            {
                t.Start("Add Free Form Element");

                var freeFormElement = FreeFormElement.Create(
                    family_doc, intersectedSolid);

                t.Commit();
            }

            string dir = Path.GetTempPath();

            string filepath = Path.Combine(dir,
                                           "floor_intersection_family.rfa");

            SaveAsOptions sao = new SaveAsOptions()
            {
                OverwriteExistingFile = true
            };

            family_doc.SaveAs(filepath, sao);

            // Create 3D View

            var viewFamilyType
                = new FilteredElementCollector(family_doc)
                  .OfClass(typeof(ViewFamilyType))
                  .OfType <ViewFamilyType>()
                  .FirstOrDefault(x =>
                                  x.ViewFamily == ViewFamily.ThreeDimensional);

            View3D threeDView;

            using (var t = new Transaction(family_doc))
            {
                t.Start("Create 3D View");

                threeDView = View3D.CreateIsometric(
                    family_doc, viewFamilyType.Id);

                t.Commit();
            }

            // Export to SAT

            var viewSet = new List <ElementId>()
            {
                threeDView.Id
            };

            SATExportOptions exportOptions
                = new SATExportOptions();

            var res = family_doc.Export(dir,
                                        "SolidFile.sat", viewSet, exportOptions);

            return(Result.Succeeded);
        }
示例#21
0
 /// <summary>
 /// Boolean intersect geometric operation, return a new solid as the result
 /// </summary>
 /// <param name="solid1">Operation solid 1</param>
 /// <param name="solid2">Operation solid 2</param>
 /// <returns>The operation result</returns>
 public static Solid BooleanOperation_Intersect(Solid solid1, Solid solid2)
 {
     return(BooleanOperationsUtils.ExecuteBooleanOperation(solid1, solid2, BooleanOperationsType.Intersect));
 }
示例#22
0
        /// <summary>
        /// Creates a negative block family from the geometry of the target element and boundaries.
        /// </summary>
        /// <remarks>This is the main implementation of the sample command.</remarks>
        /// <param name="targetElement">The target solid element.</param>
        /// <param name="boundaries">The selected curve element boundaries.</param>
        /// <param name="familyLoadOptions">The family load options when loading the new family.</param>
        /// <param name="familyTemplate">The family template.</param>
        public static FailureCondition CreateNegativeBlock(Element targetElement, IList <Reference> boundaries, IFamilyLoadOptions familyLoadOptions, String familyTemplate)
        {
            Document doc = targetElement.Document;

            Autodesk.Revit.ApplicationServices.Application app = doc.Application;

            // Get curve loop for boundary
            IList <Curve> curves = GetContiguousCurvesFromSelectedCurveElements(doc, boundaries);
            CurveLoop     loop   = null;

            try
            {
                loop = CurveLoop.Create(curves);
            }
            catch (Autodesk.Revit.Exceptions.ArgumentException)
            {
                // Curves are not contiguous
                return(FailureCondition.CurvesNotContigous);
            }
            List <CurveLoop> loops = new List <CurveLoop>();

            loops.Add(loop);

            // Get elevation of loop
            double elevation = curves[0].GetEndPoint(0).Z;

            // Get height for extrusion
            BoundingBoxXYZ bbox   = targetElement.get_BoundingBox(null);
            double         height = bbox.Max.Z - elevation;

            if (height <= 1e-5)
            {
                return(FailureCondition.CurveLoopAboveTarget);
            }

            height += 1;

            // Create family
            Document familyDoc = app.NewFamilyDocument(familyTemplate);

            // Create block from boundaries
            Solid block = GeometryCreationUtilities.CreateExtrusionGeometry(loops, XYZ.BasisZ, height);

            // Subtract target element
            IList <Solid> fromElement = GetTargetSolids(targetElement);

            int solidCount = fromElement.Count;

            // Merge all found solids into single one
            Solid toSubtract = null;

            if (solidCount == 1)
            {
                toSubtract = fromElement[0];
            }

            else if (solidCount > 1)
            {
                toSubtract =
                    BooleanOperationsUtils.ExecuteBooleanOperation(fromElement[0], fromElement[1], BooleanOperationsType.Union);
            }

            if (solidCount > 2)
            {
                for (int i = 2; i < solidCount; i++)
                {
                    toSubtract = BooleanOperationsUtils.ExecuteBooleanOperation(toSubtract, fromElement[i],
                                                                                BooleanOperationsType.Union);
                }
            }

            // Subtract merged solid from overall block
            try
            {
                BooleanOperationsUtils.ExecuteBooleanOperationModifyingOriginalSolid(block, toSubtract,
                                                                                     BooleanOperationsType.Difference);
            }
            catch (Autodesk.Revit.Exceptions.InvalidOperationException)
            {
                return(FailureCondition.NoIntersection);
            }

            // Create freeform element
            using (Transaction t = new Transaction(familyDoc, "Add element"))
            {
                t.Start();
                RevitFreeFormElement element = Autodesk.Revit.DB.FreeFormElement.Create(familyDoc, block);
                t.Commit();
            }

            // Load family into document
            Family family = familyDoc.LoadFamily(doc, familyLoadOptions);

            familyDoc.Close(false);

            // Get symbol as first symbol of loaded family
            FilteredElementCollector collector = new FilteredElementCollector(doc);

            collector.WherePasses(new FamilySymbolFilter(family.Id));
            FamilySymbol fs = collector.FirstElement() as FamilySymbol;


            // Place instance at location of original curves
            using (Transaction t2 = new Transaction(doc, "Place instance"))
            {
                t2.Start();
                doc.Create.NewFamilyInstance(XYZ.Zero, fs, Autodesk.Revit.DB.Structure.StructuralType.NonStructural);
                t2.Commit();
            }

            return(FailureCondition.Success);
        }
示例#23
0
        /// <summary>
        /// 处理碰撞
        /// </summary>
        /// <param name="doc"></param>
        /// <param name="hostELemID"></param>
        /// <param name="sd"></param>
        /// <returns></returns>
        public static Solid SolidHandle(Document doc, ElementId hostELemID, Solid sd)
        {
            //TODO:这里是取得该物体是否剪切别的物体
            Element hostElem = doc.GetElement(hostELemID);
            //碰撞集合
            List <Element> elembeCutList = JoinGeometryUtils.GetJoinedElements(doc, hostElem).Where(m =>
            {
                if (JoinGeometryUtils.AreElementsJoined(doc, doc.GetElement(m), hostElem))
                {
                    //if (JoinGeometryUtils.IsCuttingElementInJoin(doc, hostElem, doc.GetElement(m)))
                    //{
                    return(true);
                    //}
                }
                return(false);
            }).ToList().ConvertAll(m => doc.GetElement(m));

            //对于与梁进行碰撞的Solid的处理
            if (hostElem.Category.Id == new ElementId(BuiltInCategory.OST_StructuralFraming))
            {
                try
                {
                    elembeCutList = elembeCutList.Where(m => m.Category
                                                        .Id == new ElementId(BuiltInCategory.OST_StructuralFraming) || m.Category.Id.IntegerValue == (int)BuiltInCategory.OST_StructuralColumns).ToList();
                }
                catch { SWF.MessageBox.Show(hostELemID + ""); }
            }
            else if (hostElem is Floor)
            {
                elembeCutList = elembeCutList.Where(m => m.Category.Id == new ElementId(BuiltInCategory.OST_StructuralFraming) ||
                                                    m.Category.Id == new ElementId(BuiltInCategory.OST_StructuralColumns) || m.Category.Id == new ElementId(BuiltInCategory.OST_Walls))
                                .ToList();
            }
            else if (hostElem.Category.Id.IntegerValue == (int)BuiltInCategory.OST_StructuralColumns)
            {
                elembeCutList = elembeCutList.Where(m => m is Wall && m.Name.Contains("DW")).ToList();
            }
            else if (hostElem is Wall)
            {
                Curve walCurve   = (hostElem.Location as LocationCurve).Curve;
                XYZ   startPoint = walCurve.GetEndPoint(0);
                XYZ   endPoint   = walCurve.GetEndPoint(1);
                startPoint = new XYZ(startPoint.X, startPoint.Y, 0);
                endPoint   = new XYZ(endPoint.X, endPoint.Y, 0);
                List <Element> walElemList = bc.FilterElementList <Wall>(doc).Where(m =>
                {
                    if (hostElem.Id == m.Id)
                    {
                        return(false);
                    }
                    if (!hostElem.Name.Contains("DW"))
                    {
                        return(false);
                    }
                    if (hostElem.LevelId != m.LevelId)
                    {
                        return(false);
                    }
                    Curve mc = (m.Location as LocationCurve).Curve;
                    XYZ sp   = mc.GetEndPoint(0);
                    XYZ ep   = mc.GetEndPoint(1);
                    sp       = new XYZ(sp.X, sp.Y, 0);
                    ep       = new XYZ(ep.X, ep.Y, 0);
                    if (sp.IsAlmostEqualTo(startPoint) || sp.IsAlmostEqualTo(endPoint) || ep.IsAlmostEqualTo(endPoint) || ep.IsAlmostEqualTo(startPoint))
                    {
                        return(true);
                    }
                    return(false);
                }).ToList();
                elembeCutList = elembeCutList.Where(m => m.Category.Id.IntegerValue == (int)BuiltInCategory.OST_StructuralColumns || (m is Wall && m.Name.Contains("DW"))).ToList();
                elembeCutList.AddRange(walElemList);
            }
            Solid lastSolid = sd;

            foreach (Element e in elembeCutList)
            {
                Solid sdcut = AllSolid_Of_Element(e)[0];
                try
                {
                    lastSolid = BooleanOperationsUtils.ExecuteBooleanOperation(lastSolid, sdcut, BooleanOperationsType.Difference);
                }//可能由于几何体太过复杂导致Bool失败
                catch { }
            }
            return(lastSolid);
        }
示例#24
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);
        }
        /// <summary>
        /// Execute a Boolean operation, and catch the exception.
        /// </summary>
        /// <param name="id">The id of the object demanding the Boolean operation.</param>
        /// <param name="secondId">The id of the object providing the second solid.</param>
        /// <param name="firstSolid">The first solid parameter to ExecuteBooleanOperation.</param>
        /// <param name="secondSolid">The second solid parameter to ExecuteBooleanOperation.</param>
        /// <param name="opType">The Boolean operation type.</param>
        /// <param name="suggestedShiftDirection">If the Boolean operation fails, a unit vector used to retry with a small shift.  Can be null.</param>
        /// <returns>The result of the Boolean operation, or the first solid if the operation fails.</returns>
        public static Solid ExecuteSafeBooleanOperation(int id, int secondId, Solid firstSolid, Solid secondSolid, BooleanOperationsType opType, XYZ suggestedShiftDirection)
        {
            const double footToMillimeter = 1.0 / 304.8;

            // Perform default operations if one of the arguments is null.
            if (firstSolid == null || secondSolid == null)
            {
                if (firstSolid == null && secondSolid == null)
                {
                    return(null);
                }

                switch (opType)
                {
                case BooleanOperationsType.Union:
                {
                    if (firstSolid == null)
                    {
                        return(secondSolid);
                    }

                    return(firstSolid);
                }

                case BooleanOperationsType.Difference:
                {
                    if (firstSolid == null)
                    {
                        return(null);
                    }

                    return(firstSolid);
                }

                default:
                    // for .Intersect
                    return(null);
                }
            }

            Solid resultSolid       = null;
            bool  failedAllAttempts = true;

            // We will attempt to do the Boolean operation 3 times:
            // 1st pass: With the passed-in arguments.
            // 2nd pass: With a 1mm shift in a direction in suggestedShiftDirection, or +Z if suggestedShiftDirection is null
            // 3rd pass: With a 1mm shift in a direction in -suggestedShiftDirection, or -Z if suggestedShiftDirection is null
            for (int ii = 0; ii < 3; ii++)
            {
                try
                {
                    resultSolid = null;

                    Solid secondOperand = secondSolid;
                    if (ii > 0)
                    {
                        // 1 mm shift.
                        XYZ       shiftDirection   = (suggestedShiftDirection == null) ? new XYZ(0, 0, 1) : suggestedShiftDirection;
                        Transform secondSolidShift = Transform.CreateTranslation(shiftDirection * ((ii == 1) ? footToMillimeter : -footToMillimeter));
                        secondOperand = SolidUtils.CreateTransformed(secondOperand, secondSolidShift);
                    }

                    resultSolid       = BooleanOperationsUtils.ExecuteBooleanOperation(firstSolid, secondOperand, opType);
                    failedAllAttempts = false;
                }
                catch (Exception ex)
                {
                    if (ii < 2)
                    {
                        continue;
                    }

                    Importer.TheLog.LogError(id, ex.Message, false);
                    resultSolid = firstSolid;
                }

                if (SolidValidator.IsValidGeometry(resultSolid))
                {
                    // If we got here not on out first attempt, generate a warning, unless we got here because we gave up on our 3rd attempt.
                    if (ii > 0 && !failedAllAttempts)
                    {
                        Importer.TheLog.LogWarning(id, "The second argument in the Boolean " +
                                                   opType.ToString() +
                                                   " operation was shifted by 1mm to allow the operation to succeed.  This may result in a very small difference in appearance.", false);
                    }
                    return(resultSolid);
                }
            }

            Importer.TheLog.LogError(id, opType.ToString() + " operation failed with void from #" + secondId.ToString(), false);
            return(firstSolid);
        }
示例#26
0
 /// <summary>
 /// Boolean difference geometric operation, return a new solid as the result
 /// </summary>
 /// <param name="solid1">Operation solid 1</param>
 /// <param name="solid2">Operation solid 2</param>
 /// <returns>The operation result</returns>
 public static Solid BooleanOperation_Difference(Solid solid1, Solid solid2)
 {
     return(BooleanOperationsUtils.ExecuteBooleanOperation(solid1, solid2, BooleanOperationsType.Difference));
 }
示例#27
0
        /// <summary>
        /// Retrieve all plan view boundary loops from
        /// all solids of the given element geometry
        /// united together.
        /// </summary>
        internal static JtLoops GetPlanViewBoundaryLoopsGeo(
            Autodesk.Revit.Creation.Application creapp,
            GeometryElement geo,
            ref int nFailures)
        {
            Solid union = null;

            Plane plane = new Plane(XYZ.BasisX,
                                    XYZ.BasisY, XYZ.Zero);

            foreach (GeometryObject obj in geo)
            {
                Solid solid = obj as Solid;

                if (null != solid &&
                    0 < solid.Faces.Size)
                {
                    // Some solids, e.g. in the standard
                    // content 'Furniture Chair - Office'
                    // cause an extrusion analyser failure,
                    // so skip adding those.

                    try
                    {
                        ExtrusionAnalyzer extrusionAnalyzer
                            = ExtrusionAnalyzer.Create(
                                  solid, plane, XYZ.BasisZ);
                    }
                    catch (Autodesk.Revit.Exceptions
                           .InvalidOperationException)
                    {
                        solid = null;
                        ++nFailures;
                    }

                    if (null != solid)
                    {
                        if (null == union)
                        {
                            union = solid;
                        }
                        else
                        {
                            try
                            {
                                union = BooleanOperationsUtils
                                        .ExecuteBooleanOperation(union, solid,
                                                                 BooleanOperationsType.Union);
                            }
                            catch (Autodesk.Revit.Exceptions
                                   .InvalidOperationException)
                            {
                                ++nFailures;
                            }
                        }
                    }
                }
            }

            JtLoops loops = new JtLoops(1);

            AddLoops(creapp, loops, union, ref nFailures);

            return(loops);
        }
示例#28
0
        /// <summary>
        /// Gets the rectangular openings.
        /// </summary>
        /// <returns></returns>
        /// <remarks>This method uses walls, doors, windows and generic models bounding boxes to determine the rectangles.
        /// These objects can be in the host file or in linked Revit files.</remarks>
        public static IList <Autodesk.DesignScript.Geometry.Rectangle> GetRectangularOpenings()
        {
            Utils.Log(string.Format("OpeningUtils.GetRectangularOpenings started...", ""));

            Autodesk.Revit.DB.Document doc = DocumentManager.Instance.CurrentDBDocument;

            //look for Walls, Doors, Windows, Generic Models in the current document and in the linked documents
            ElementCategoryFilter wallFilter    = new ElementCategoryFilter(BuiltInCategory.OST_Walls);
            ElementCategoryFilter doorFilter    = new ElementCategoryFilter(BuiltInCategory.OST_Doors);
            ElementCategoryFilter windowFilter  = new ElementCategoryFilter(BuiltInCategory.OST_Windows);
            ElementCategoryFilter genericFilter = new ElementCategoryFilter(BuiltInCategory.OST_GenericModel);

            IList <ElementFilter> filterList = new List <ElementFilter>()
            {
                wallFilter, doorFilter, windowFilter, genericFilter
            };

            LogicalOrFilter orFilter = new LogicalOrFilter(filterList);

            IList <Autodesk.DesignScript.Geometry.Solid> solids = new List <Autodesk.DesignScript.Geometry.Solid>();

            IList <Autodesk.DesignScript.Geometry.Rectangle> output = new List <Autodesk.DesignScript.Geometry.Rectangle>();

            foreach (Autodesk.Revit.DB.Element e in new FilteredElementCollector(doc)
                     .WherePasses(orFilter)
                     .WhereElementIsNotElementType()
                     .Where(x =>
                            x.Parameters.Cast <Autodesk.Revit.DB.Parameter>()
                            .First(p => p.Id.IntegerValue == (int)BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS).HasValue))
            {
                string comments = e.Parameters.Cast <Autodesk.Revit.DB.Parameter>().First(p => p.Id.IntegerValue == (int)BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS).AsString();

                if (comments.ToLower() != "opening")
                {
                    continue;
                }

                Transform tr = Transform.Identity;

                if (e is Instance)
                {
                    Instance instance = e as Instance;
                    tr = instance.GetTotalTransform();
                }

                IList <Autodesk.Revit.DB.Solid> temp = new List <Autodesk.Revit.DB.Solid>();

                foreach (GeometryObject go in e.get_Geometry(new Options()))
                {
                    if (go is GeometryInstance)
                    {
                        GeometryInstance geoInstance = go as GeometryInstance;

                        foreach (var gi in geoInstance.SymbolGeometry)
                        {
                            if (gi is Autodesk.Revit.DB.Solid)
                            {
                                Autodesk.Revit.DB.Solid s = gi as Autodesk.Revit.DB.Solid;
                                s = SolidUtils.CreateTransformed(s, tr);
                                temp.Add(s);
                            }
                        }
                    }
                    else
                    {
                        if (go is Autodesk.Revit.DB.Solid)
                        {
                            Autodesk.Revit.DB.Solid s = go as Autodesk.Revit.DB.Solid;
                            s = SolidUtils.CreateTransformed(s, tr);
                            temp.Add(s);
                        }
                    }
                }

                if (temp.Count > 0)
                {
                    Autodesk.Revit.DB.Solid s0 = temp[0];
                    for (int i = 1; i < temp.Count; ++i)
                    {
                        s0 = BooleanOperationsUtils.ExecuteBooleanOperation(s0, temp[i], BooleanOperationsType.Union);
                    }

                    solids.Add(s0.ToProtoType());
                }
            }

            foreach (RevitLinkInstance rli in new FilteredElementCollector(doc).OfClass(typeof(RevitLinkInstance)).WhereElementIsNotElementType())
            {
                Autodesk.Revit.DB.Document link = rli.GetLinkDocument();

                foreach (Autodesk.Revit.DB.Element e in new FilteredElementCollector(link)
                         .WherePasses(orFilter)
                         .WhereElementIsNotElementType()
                         .Where(x =>
                                x.Parameters.Cast <Autodesk.Revit.DB.Parameter>()
                                .First(p => p.Id.IntegerValue == (int)BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS).HasValue))
                {
                    Transform tr = rli.GetTotalTransform();

                    string comments = e.Parameters.Cast <Autodesk.Revit.DB.Parameter>().First(p => p.Id.IntegerValue == (int)BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS).AsString();

                    if (comments.ToLower() != "opening")
                    {
                        continue;
                    }

                    if (e is Instance)
                    {
                        Instance instance = e as Instance;
                        tr = tr.Multiply(instance.GetTotalTransform());
                    }

                    IList <Autodesk.Revit.DB.Solid> temp = new List <Autodesk.Revit.DB.Solid>();

                    foreach (var go in e.get_Geometry(new Options()))
                    {
                        if (go is GeometryInstance)
                        {
                            GeometryInstance geoInstance = go as GeometryInstance;

                            foreach (var gi in geoInstance.SymbolGeometry)
                            {
                                if (gi is Autodesk.Revit.DB.Solid)
                                {
                                    Autodesk.Revit.DB.Solid s = gi as Autodesk.Revit.DB.Solid;
                                    s = SolidUtils.CreateTransformed(s, tr);
                                    temp.Add(s);
                                }
                            }
                        }
                        else
                        {
                            if (go is Autodesk.Revit.DB.Solid)
                            {
                                Autodesk.Revit.DB.Solid s = go as Autodesk.Revit.DB.Solid;
                                s = SolidUtils.CreateTransformed(s, tr);
                                temp.Add(s);
                            }
                        }
                    }

                    if (temp.Count > 0)
                    {
                        Autodesk.Revit.DB.Solid s0 = temp[0];
                        for (int i = 1; i < temp.Count; ++i)
                        {
                            s0 = BooleanOperationsUtils.ExecuteBooleanOperation(s0, temp[i], BooleanOperationsType.Union);
                        }

                        solids.Add(s0.ToProtoType());
                    }
                }
            }

            foreach (var s in solids)
            {
                IList <Autodesk.DesignScript.Geometry.Point> points = new List <Autodesk.DesignScript.Geometry.Point>();

                foreach (var v in s.Vertices)
                {
                    points.Add(v.PointGeometry);
                }

                points = Autodesk.DesignScript.Geometry.Point.PruneDuplicates(points);

                Autodesk.DesignScript.Geometry.Plane plane = Autodesk.DesignScript.Geometry.Plane.ByBestFitThroughPoints(points);

                plane = Autodesk.DesignScript.Geometry.Plane.ByOriginNormal(points.Last(), plane.Normal);

                IList <Autodesk.DesignScript.Geometry.Point> temp = new List <Autodesk.DesignScript.Geometry.Point>();

                foreach (var p in points)
                {
                    foreach (var q in p.Project(plane, plane.Normal))
                    {
                        temp.Add(q as Autodesk.DesignScript.Geometry.Point);
                    }

                    foreach (var q in p.Project(plane, plane.Normal.Reverse()))
                    {
                        temp.Add(q as Autodesk.DesignScript.Geometry.Point);
                    }
                }

                temp = Autodesk.DesignScript.Geometry.Point.PruneDuplicates(temp);

                CoordinateSystem cs = CoordinateSystem.ByPlane(plane);

                IList <Autodesk.DesignScript.Geometry.Point> relative = new List <Autodesk.DesignScript.Geometry.Point>();

                foreach (var p in temp)
                {
                    relative.Add(p.Transform(cs.Inverse()) as Autodesk.DesignScript.Geometry.Point);
                }

                var min = Autodesk.DesignScript.Geometry.Point.ByCoordinates(relative.Min(p => p.X),
                                                                             relative.Min(p => p.Y),
                                                                             relative.Min(p => p.Z));

                var max = Autodesk.DesignScript.Geometry.Point.ByCoordinates(relative.Max(p => p.X),
                                                                             relative.Max(p => p.Y),
                                                                             relative.Max(p => p.Z));

                double width  = max.X - min.X;
                double height = max.Y - min.Y;

                min = min.Transform(cs) as Autodesk.DesignScript.Geometry.Point;
                max = max.Transform(cs) as Autodesk.DesignScript.Geometry.Point;

                plane = Autodesk.DesignScript.Geometry.Plane.ByOriginNormal(Autodesk.DesignScript.Geometry.Line.ByStartPointEndPoint(min, max).PointAtParameter(0.5), plane.Normal);

                Autodesk.DesignScript.Geometry.Rectangle rectangle = Autodesk.DesignScript.Geometry.Rectangle.ByWidthLength(plane,
                                                                                                                            width,
                                                                                                                            height);

                output.Add(rectangle);

                plane.Dispose();
                cs.Dispose();
                min.Dispose();
                max.Dispose();
            }

            Utils.Log(string.Format("OpeningUtils.GetRectangularOpenings completed.", ""));

            return(output);
        }
示例#29
0
        /// <summary>
        /// This method takes the solidsList and clips all of its solids between the given range.
        /// </summary>
        /// <param name="elem">
        /// The Element from which we obtain our BoundingBoxXYZ.
        /// </param>
        /// <param name="geomElem">
        /// The top-level GeometryElement from which to gather X and Y coordinates for the intersecting solid.
        /// </param>
        /// <param name="range">
        /// The IFCRange whose Z values we use to create an intersecting solid to clip the solids in this class's internal solidsList.
        /// If range boundaries are equal, method returns, performing no clippings.
        /// </param>
        public void ClipSolidsList(GeometryElement geomElem, IFCRange range)
        {
            if (geomElem == null)
            {
                throw new ArgumentNullException("geomElemToUse");
            }
            if (MathUtil.IsAlmostEqual(range.Start, range.End) || solidsList.Count == 0)
            {
                return;
            }

            double bottomZ;
            double boundDifference;

            if (range.Start < range.End)
            {
                bottomZ         = range.Start;
                boundDifference = range.End - range.Start;
            }
            else
            {
                bottomZ         = range.End;
                boundDifference = range.Start - range.End;
            }

            // create a new solid using the X and Y of the bounding box on the top level GeometryElement and the Z of the IFCRange
            BoundingBoxXYZ elemBoundingBox = geomElem.GetBoundingBox();
            XYZ            pointA          = new XYZ(elemBoundingBox.Min.X, elemBoundingBox.Min.Y, bottomZ);
            XYZ            pointB          = new XYZ(elemBoundingBox.Max.X, elemBoundingBox.Min.Y, bottomZ);
            XYZ            pointC          = new XYZ(elemBoundingBox.Max.X, elemBoundingBox.Max.Y, bottomZ);
            XYZ            pointD          = new XYZ(elemBoundingBox.Min.X, elemBoundingBox.Max.Y, bottomZ);

            List <Curve> perimeter = new List <Curve>();

            perimeter.Add(Line.CreateBound(pointA, pointB));
            perimeter.Add(Line.CreateBound(pointB, pointC));
            perimeter.Add(Line.CreateBound(pointC, pointD));
            perimeter.Add(Line.CreateBound(pointD, pointA));

            List <CurveLoop> boxPerimeterList = new List <CurveLoop>();

            boxPerimeterList.Add(CurveLoop.Create(perimeter));
            Solid intersectionSolid = GeometryCreationUtilities.CreateExtrusionGeometry(boxPerimeterList, XYZ.BasisZ, boundDifference);

            // cycle through the elements in solidsList and intersect them against intersectionSolid to create a new list
            List <Solid> clippedSolidsList = new List <Solid>();
            Solid        currSolid;

            foreach (Solid solid in solidsList)
            {
                try
                {
                    // ExecuteBooleanOperation can throw if it fails.  In this case, just ignore the clipping.
                    currSolid = BooleanOperationsUtils.ExecuteBooleanOperation(solid, intersectionSolid, BooleanOperationsType.Intersect);
                    if (currSolid != null && currSolid.Volume != 0)
                    {
                        clippedSolidsList.Add(currSolid);
                    }
                }
                catch
                {
                }
            }
            solidsList = clippedSolidsList;
        }
示例#30
0
 /// <summary>
 /// Boolean union geometric operation, return a new solid as the result
 /// </summary>
 /// <param name="solid1">Operation solid 1</param>
 /// <param name="solid2">Operation solid 2</param>
 /// <returns>The operation result</returns>
 public static Solid BooleanOperation_Union(Solid solid1, Solid solid2)
 {
     return(BooleanOperationsUtils.ExecuteBooleanOperation(solid1, solid2, BooleanOperationsType.Union));
 }