Exemple #1
0
        /// <summary>
        /// Implement this method as an external command for Revit.
        /// </summary>
        /// <param name="commandData">An object that is passed to the external application
        /// which contains data related to the command,
        /// such as the application object and active view.</param>
        /// <param name="message">A message that can be set by the external application
        /// which will be displayed if a failure or cancellation is returned by
        /// the external command.</param>
        /// <param name="elements">A set of elements to which the external application
        /// can add elements that are to be highlighted in case of failure or cancellation.</param>
        /// <returns>Return the status of the external command.
        /// A result of Succeeded means that the API external method functioned as expected.
        /// Cancelled can be used to signify that the user cancelled the external operation
        /// at some point. Failure should be returned if the application is unable to proceed with
        /// the operation.</returns>
        public virtual Autodesk.Revit.UI.Result Execute(ExternalCommandData commandData
                                                        , ref string message, Autodesk.Revit.DB.ElementSet elements)
        {
            if (null == s_appCreation)
            {
                // share for class Intersection.
                s_appCreation = commandData.Application.Application.Create;
            }

            UIDocument             doc = commandData.Application.ActiveUIDocument;
            CombinableElementArray solids
                = new CombinableElementArray();

            ElementSet es = new ElementSet();

            foreach (ElementId elemId in es)
            {
                es.Insert(doc.Document.GetElement(elemId));
            }
            if (0 < es.Size)
            {
                foreach (Autodesk.Revit.DB.ElementId elementId in doc.Selection.GetElementIds())
                {
                    Autodesk.Revit.DB.Element element = doc.Document.GetElement(elementId);
                    System.Diagnostics.Trace.WriteLine(element.GetType().ToString());

                    GenericForm gf = element as GenericForm;
                    if (null != gf && !gf.IsSolid)
                    {
                        continue;
                    }

                    CombinableElement ce = element as CombinableElement;
                    if (null != ce)
                    {
                        solids.Append(ce);
                    }
                }

                if (solids.Size < 2)
                {
                    message = "At least 2 combinable elements should be selected.";
                    return(Autodesk.Revit.UI.Result.Failed);
                }

                doc.Document.CombineElements(solids);

                //The selected generic forms are joined, whether or not they overlap.
                return(Autodesk.Revit.UI.Result.Succeeded);
            }

            AutoJoin autojoin = new AutoJoin();

            autojoin.Join(doc.Document);
            //All overlapping generic forms are joined.

            return(Autodesk.Revit.UI.Result.Succeeded);
        }
Exemple #2
0
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            var uidoc    = commandData.Application.ActiveUIDocument;
            var doc      = uidoc.Document;
            var connForm = new ConnectElmFrm(uidoc);

            if (connForm.ShowDialog() != DialogResult.OK)
            {
                return(Result.Cancelled);
            }

            doc.AutoTransaction(() =>
            {
                var combins = new CombinableElementArray();
                var elms    = connForm.Elms;

                elms.OfType <CombinableElement>().ToList().ForEach(f => combins.Append(f));

                if (doc.IsFamilyDocument && combins.Size >= 2)
                {
                    doc.CombineElements(combins);
                }
                else if (!doc.IsFamilyDocument && elms.Count >= 2)
                {
                    elms.ForEach(f1 => elms.ForEach(f2 =>
                    {
                        ExceptionUtil.AutoTry(() =>
                        {
                            if (f1 == f2)
                            {
                                return;
                            }

                            if (!doc.CrossSpaceBox(f1, f2))
                            {
                                return;
                            }

                            JoinGeometryUtils.JoinGeometry(doc, f1, f2);
                        });
                    }));
                }
            });

            return(Result.Succeeded);
        }
Exemple #3
0
        /// <summary>
        /// Implement this method as an external command for Revit.
        /// </summary>
        /// <param name="commandData">An object that is passed to the external application
        /// which contains data related to the command,
        /// such as the application object and active view.</param>
        /// <param name="message">A message that can be set by the external application
        /// which will be displayed if a failure or cancellation is returned by
        /// the external command.</param>
        /// <param name="elements">A set of elements to which the external application
        /// can add elements that are to be highlighted in case of failure or cancellation.</param>
        /// <returns>Return the status of the external command.
        /// A result of Succeeded means that the API external method functioned as expected.
        /// Cancelled can be used to signify that the user cancelled the external operation 
        /// at some point. Failure should be returned if the application is unable to proceed with
        /// the operation.</returns>
        public virtual Autodesk.Revit.UI.Result Execute(ExternalCommandData commandData
            , ref string message, Autodesk.Revit.DB.ElementSet elements)
        {
            if (null == s_appCreation)
            {
                // share for class Intersection.
                s_appCreation = commandData.Application.Application.Create;
            }

            UIDocument doc = commandData.Application.ActiveUIDocument;
            CombinableElementArray solids
                = new CombinableElementArray();

            if (0 < doc.Selection.Elements.Size)
            {
                foreach (Autodesk.Revit.DB.Element element in doc.Selection.Elements)
                {
                    System.Diagnostics.Trace.WriteLine(element.GetType().ToString());

                    GenericForm gf = element as GenericForm;
                    if (null != gf && !gf.IsSolid)
                        continue;

                    CombinableElement ce = element as CombinableElement;
                    if (null != ce)
                        solids.Append(ce);
                }

                if (solids.Size < 2)
                {
                    message = "At least 2 combinable elements should be selected.";
                    return Autodesk.Revit.UI.Result.Failed;
                }

                doc.Document.CombineElements(solids);

                //The selected generic forms are joined, whether or not they overlap.
                return Autodesk.Revit.UI.Result.Succeeded;
            }

            AutoJoin autojoin = new AutoJoin();
            autojoin.Join(doc.Document);
            //All overlapping generic forms are joined.

            return Autodesk.Revit.UI.Result.Succeeded;
        }
Exemple #4
0
        /// <summary>
        /// Implement this method as an external command for Revit.
        /// </summary>
        /// <param name="commandData">An object that is passed to the external application
        /// which contains data related to the command,
        /// such as the application object and active view.</param>
        /// <param name="message">A message that can be set by the external application
        /// which will be displayed if a failure or cancellation is returned by
        /// the external command.</param>
        /// <param name="elements">A set of elements to which the external application
        /// can add elements that are to be highlighted in case of failure or cancellation.</param>
        /// <returns>Return the status of the external command.
        /// A result of Succeeded means that the API external method functioned as expected.
        /// Cancelled can be used to signify that the user cancelled the external operation
        /// at some point. Failure should be returned if the application is unable to proceed with
        /// the operation.</returns>
        public Autodesk.Revit.UI.Result Execute(ExternalCommandData commandData, ref string message,
                                                ElementSet elements)
        {
            // set out default result to failure.
            Autodesk.Revit.UI.Result retRes = Autodesk.Revit.UI.Result.Failed;
            m_application     = commandData.Application.Application;
            m_document        = commandData.Application.ActiveUIDocument.Document;
            f                 = m_document.FamilyCreate;
            extrusions        = new Extrusion[5];
            m_combineElements = new CombinableElementArray();

            m_transaction = new Transaction(m_document, "External Tool");
            m_transaction.Start();

            if (m_document.OwnerFamily.FamilyCategory.Name !=
                m_document.Settings.Categories.get_Item(BuiltInCategory.OST_MechanicalEquipment).Name) // FamilyCategory.Name is not "Mechanical Equipment".
            {
                message = "Please make sure you opened a template of Mechanical Equipment.";
                return(retRes);
            }

            try
            {
                CreateExtrusions();
                m_document.Regenerate();
                CreateConnectors();
                m_document.Regenerate();
                m_document.CombineElements(m_combineElements);
                m_document.Regenerate();
            }
            catch (Exception x)
            {
                m_transaction.RollBack();
                message = x.Message;
                return(retRes);
            }

            m_transaction.Commit();

            retRes = Autodesk.Revit.UI.Result.Succeeded;
            return(retRes);
        }
Exemple #5
0
        /// <summary>
        /// Join the overlapped elements in the list.
        /// </summary>
        /// <param name="elements">the element list may includes overlapping.</param>
        /// <param name="document">the active document</param>
        /// <returns>the joined geometry combination, the joined elements is removed from the list.</returns>
        public GeomCombination JoinOverlapping(List <CombinableElement> elements, Document document)
        {
            CombinableElementArray joinedElements = new CombinableElementArray();

            // try to find the first overlapping.
            foreach (CombinableElement aElement in elements)
            {
                foreach (CombinableElement xElement in elements)
                {
                    if (IsOverlapped(aElement, xElement))
                    {
                        joinedElements.Append(aElement);
                        break;
                    }
                }
                if (1 == joinedElements.Size)
                {
                    break;
                }
            }

            if (0 == joinedElements.Size)
            {
                return(null);//Can not find any overlapping.
            }

            // try to find all elements overlapped the first element.
            foreach (CombinableElement aElement in elements)
            {
                if (IsOverlapped(aElement, joinedElements.get_Item(0)))
                {
                    joinedElements.Append(aElement);
                }
            }

            List <CombinableElement> allCanJoin = new List <CombinableElement>();
            bool isNew = false;

            do
            {
                allCanJoin.Clear();
                isNew = false;

                // try to find all elements overlapped joinedElements
                foreach (CombinableElement aElement in joinedElements)
                {
                    foreach (CombinableElement xElement in elements)
                    {
                        if (IsOverlapped(aElement, xElement))
                        {
                            allCanJoin.Add(xElement);
                        }
                    }
                }

                foreach (CombinableElement aElement in allCanJoin)
                {
                    bool isContained = false;

                    for (int ii = 0; ii < joinedElements.Size; ii++)
                    {
                        if (aElement.Id.IntegerValue == joinedElements.get_Item(ii).Id.IntegerValue)
                        {
                            isContained = true;
                            break;
                        }
                    }

                    if (!isContained)
                    {
                        isNew = true;
                        joinedElements.Append(aElement);
                    }
                }
            } while (isNew);// find all elements which overlapped with joined geometry combination.


            // removed the joined elements from the input list.
            foreach (CombinableElement aElement in joinedElements)
            {
                elements.Remove(aElement);
            }

            return(document.CombineElements(joinedElements));
        }
Exemple #6
0
        /// <summary>
        /// Join the overlapped elements in the list.
        /// </summary>
        /// <param name="elements">the element list may includes overlapping.</param>
        /// <param name="document">the active document</param>
        /// <returns>the joined geometry combination, the joined elements is removed from the list.</returns>
        public GeomCombination JoinOverlapping(List<CombinableElement> elements, Document document)
        {
            CombinableElementArray joinedElements = new CombinableElementArray();

            // try to find the first overlapping.
            foreach (CombinableElement aElement in elements)
            {
                foreach (CombinableElement xElement in elements)
                {
                    if (IsOverlapped(aElement, xElement))
                    {
                        joinedElements.Append(aElement);
                        break;
                    }
                }
                if (1 == joinedElements.Size)
                    break;
            }

            if (0 == joinedElements.Size)
            {
                return null;//Can not find any overlapping.
            }

            // try to find all elements overlapped the first element.
            foreach (CombinableElement aElement in elements)
            {
                if (IsOverlapped(aElement, joinedElements.get_Item(0)))
                {
                    joinedElements.Append(aElement);
                }
            }

            List<CombinableElement> allCanJoin = new List<CombinableElement>();
            bool isNew = false;
            do
            {
                allCanJoin.Clear();
                isNew = false;

                // try to find all elements overlapped joinedElements
                foreach (CombinableElement aElement in joinedElements)
                {
                    foreach (CombinableElement xElement in elements)
                    {
                        if (IsOverlapped(aElement, xElement))
                        {
                            allCanJoin.Add(xElement);
                        }
                    }
                }

                foreach (CombinableElement aElement in allCanJoin)
                {
                    bool isContained = false;

                    for (int ii = 0; ii < joinedElements.Size; ii++)
                    {
                        if (aElement.Id.IntegerValue == joinedElements.get_Item(ii).Id.IntegerValue)
                        {
                            isContained = true;
                            break;
                        }
                    }

                    if (!isContained)
                    {
                        isNew = true;
                        joinedElements.Append(aElement);
                    }
                }
            } while (isNew);// find all elements which overlapped with joined geometry combination.

            // removed the joined elements from the input list.
            foreach (CombinableElement aElement in joinedElements)
            {
                elements.Remove(aElement);
            }

            return document.CombineElements(joinedElements);
        }
Exemple #7
0
        /// <summary>
        /// Implement this method as an external command for Revit.
        /// </summary>
        /// <param name="commandData">An object that is passed to the external application 
        /// which contains data related to the command, 
        /// such as the application object and active view.</param>
        /// <param name="message">A message that can be set by the external application 
        /// which will be displayed if a failure or cancellation is returned by 
        /// the external command.</param>
        /// <param name="elements">A set of elements to which the external application 
        /// can add elements that are to be highlighted in case of failure or cancellation.</param>
        /// <returns>Return the status of the external command. 
        /// A result of Succeeded means that the API external method functioned as expected. 
        /// Cancelled can be used to signify that the user cancelled the external operation 
        /// at some point. Failure should be returned if the application is unable to proceed with 
        /// the operation.</returns>
        public Autodesk.Revit.UI.Result Execute(ExternalCommandData commandData, ref string message,
            ElementSet elements)
        {
            // set out default result to failure.
            Autodesk.Revit.UI.Result retRes = Autodesk.Revit.UI.Result.Failed;
            m_application = commandData.Application.Application;
            m_document = commandData.Application.ActiveUIDocument.Document;
            f = m_document.FamilyCreate;
            extrusions = new Extrusion[5];
            m_combineElements = new CombinableElementArray();

            m_transaction = new Transaction(m_document, "External Tool");
            m_transaction.Start();

            if (m_document.OwnerFamily.FamilyCategory.Name != "Mechanical Equipment")
            {
                message = "Please make sure you opened a template of Mechanical Equipment.";
                return retRes;
            }

            try
            {
                CreateExtrusions();
                m_document.Regenerate();
                CreateConnectors();
                m_document.Regenerate();
                m_document.CombineElements(m_combineElements);
                m_document.Regenerate();
            }
            catch(Exception x)
            {
                m_transaction.RollBack();
                message = x.Message;
                return retRes;
            }

            m_transaction.Commit();

            retRes = Autodesk.Revit.UI.Result.Succeeded;
            return retRes;
        }
Exemple #8
0
        public static Dictionary <string, object> ByRoom(string familyTemplatePath, global::Revit.Elements.Room room, string materialName, global::Revit.Elements.Category category, string subcategory = "")
        {
            //variables
            global::Revit.Elements.Element   famInstance = null;
            Autodesk.Revit.DB.FamilyInstance internalFam = null;
            bool fileFound = false;

            //the current document
            Autodesk.Revit.DB.Document doc = DocumentManager.Instance.CurrentDBDocument;
            UIApplication uiapp            = new UIApplication(doc.Application);

            //convert the room to an Autodesk.Revit.DB representation
            Autodesk.Revit.DB.Architecture.Room internalRoom = (Autodesk.Revit.DB.Architecture.Room)room.InternalElement;
            string name = internalRoom.Name;

            //we close all of the families because we need to swap documents
            foreach (Document d in uiapp.Application.Documents)
            {
                if (d.IsFamilyDocument)
                {
                    d.Close(false);
                }
            }
            //create the new family document in the background and store it in memory
            Document familyDocument = uiapp.Application.NewFamilyDocument(familyTemplatePath);
            //instantiate a material element id and try to get the material that was specified
            ElementId material = null;
            FilteredElementCollector materialCollector = new FilteredElementCollector(familyDocument).OfClass(typeof(Autodesk.Revit.DB.Material));

            foreach (var m in materialCollector)
            {
                if (m.Name.ToLower().Replace(" ", "") == materialName.ToLower().Replace(" ", ""))
                {
                    material = m.Id;
                }
            }
            //close Dynamo's open transaction, we need to do this because we open a new Revit API transaction in the family document (This is document switching)
            TransactionManager.Instance.ForceCloseTransaction();
            //start creating the families.
            Transaction trans = new Transaction(familyDocument, "Generate Families Ya'll");

            trans.Start();
            //set the family category
            Autodesk.Revit.DB.Category familyCategory = familyDocument.Settings.Categories.get_Item(category.Name);
            familyDocument.OwnerFamily.FamilyCategory = familyCategory;
            //get the subcategory for the solids
            Autodesk.Revit.DB.Category subCategory = null;
            foreach (Autodesk.Revit.DB.Category c in familyCategory.SubCategories)
            {
                if (c.Name.ToLower() == subcategory.ToLower())
                {
                    subCategory = c;
                }
            }
            //get the height of the thing
            double height = room.Height;
            //get the curves
            IList <IList <BoundarySegment> > boundary = internalRoom.GetBoundarySegments(new SpatialElementBoundaryOptions());

            //generate a plane
            Autodesk.Revit.DB.Plane       revitPlane  = Autodesk.Revit.DB.Plane.CreateByNormalAndOrigin(Vector.ZAxis().ToXyz(), new XYZ(0, 0, 0));
            Autodesk.Revit.DB.SketchPlane sketchPlane = SketchPlane.Create(familyDocument, revitPlane);
            //the curve arrays to generate solids and voids in family
            CurveArray    curveArray        = new CurveArray();
            CurveArrArray curveArrArray     = new CurveArrArray();
            CurveArray    curveArrayVoid    = new CurveArray();
            CurveArrArray curveArrArrayVoid = new CurveArrArray();
            //to perform  the cut action on the solid with the voids
            CombinableElementArray ceArray = new CombinableElementArray();
            //transform bizness
            Point            roomCentroid  = room.BoundingBox.ToCuboid().Centroid();
            Point            locationPoint = Point.ByCoordinates(roomCentroid.X, roomCentroid.Y, 0);
            CoordinateSystem oldCS         = CoordinateSystem.ByOrigin(locationPoint);
            CoordinateSystem newCS         = CoordinateSystem.ByOrigin(0, 0, 0);

            //flag to step through the boundaries.
            int flag = 0;

            while (flag < boundary.Count)
            {
                //the first set of curves is the solid's boundary
                if (flag == 0)
                {
                    //generate the solid form which is the first item in the boundary segments.
                    foreach (BoundarySegment b in boundary[flag])
                    {
                        Autodesk.DesignScript.Geometry.Curve c          = b.GetCurve().ToProtoType();
                        Autodesk.DesignScript.Geometry.Curve movedCurve = c.Transform(oldCS, newCS) as Autodesk.DesignScript.Geometry.Curve;
                        curveArray.Append(movedCurve.ToRevitType());
                    }
                    curveArrArray.Append(curveArray);
                    Extrusion solidExtrusion = familyDocument.FamilyCreate.NewExtrusion(true, curveArrArray, sketchPlane, height);
                    if (material != null)
                    {
                        //Set the material
                        Autodesk.Revit.DB.Parameter matParam = solidExtrusion.get_Parameter(BuiltInParameter.MATERIAL_ID_PARAM);
                        matParam.Set(material);
                    }
                    //try to set the subcategory
                    if (subCategory != null)
                    {
                        solidExtrusion.Subcategory = subCategory;
                    }
                }
                //subsequent lists of curves are representative of the voids
                else
                {
                    //clear the curves from the collection for all items after the second one. (index 2+)
                    if (!curveArrayVoid.IsEmpty)
                    {
                        curveArrayVoid.Clear();
                        curveArrArrayVoid.Clear();
                        ceArray.Clear();
                    }
                    //generate the void form
                    foreach (BoundarySegment b in boundary[flag])
                    {
                        Autodesk.DesignScript.Geometry.Curve c          = b.GetCurve().ToProtoType();
                        Autodesk.DesignScript.Geometry.Curve movedCurve = c.Transform(oldCS, newCS) as Autodesk.DesignScript.Geometry.Curve;
                        curveArrayVoid.Append(movedCurve.ToRevitType());
                    }
                    curveArrArrayVoid.Append(curveArrayVoid);
                    Extrusion voidExtrusion = familyDocument.FamilyCreate.NewExtrusion(false, curveArrArrayVoid, sketchPlane, height);

                    //try to combine things
                    foreach (Extrusion genericForm in new FilteredElementCollector(familyDocument).OfClass(typeof(Extrusion))
                             .Cast <Extrusion>())
                    {
                        ceArray.Append(genericForm);
                    }
                    //to add the void to the solid
                    familyDocument.CombineElements(ceArray);
                }
                flag++;
            }
            familyDocument.Regenerate();
            trans.Commit();

            Autodesk.Revit.DB.Family fam = null;
            //build the temporary path
            string familyFilePath = Path.GetTempPath() + name + ".rfa";

            SaveAsOptions opt = new SaveAsOptions();

            opt.OverwriteExistingFile = true;
            familyDocument.SaveAs(familyFilePath, opt);
            familyDocument.Close(false);

            TransactionManager.Instance.ForceCloseTransaction();
            Transaction trans2 = new Transaction(doc, "Attempting to place or update Room family instances.");

            trans2.Start();
            IFamilyLoadOptions loadOptions = new FamilyImportOptions();
            bool variable = true;

            loadOptions.OnFamilyFound(true, out variable);
            doc.LoadFamily(familyFilePath, loadOptions, out fam);

            FamilySymbol familySymbol = (FamilySymbol)doc.GetElement(fam.GetFamilySymbolIds().First());
            //try to find if it is placed already
            FilteredElementCollector col = new FilteredElementCollector(doc);
            //get built in category from user viewable category
            BuiltInCategory myCatEnum =
                (BuiltInCategory)Enum.Parse(typeof(BuiltInCategory), category.Id.ToString());

            foreach (Autodesk.Revit.DB.Element e in col.WhereElementIsNotElementType().OfCategory(myCatEnum).ToElements())
            {
                Autodesk.Revit.DB.FamilySymbol type = (FamilySymbol)doc.GetElement(e.GetTypeId());
                if (type.FamilyName.Equals(name))
                {
                    fileFound   = true;
                    internalFam = e as Autodesk.Revit.DB.FamilyInstance;
                }
            }
            //place families that are not placed
            if (fileFound == false)
            {
                if (!familySymbol.IsActive)
                {
                    familySymbol.Activate();
                }

                internalFam = doc.Create.NewFamilyInstance(new XYZ(roomCentroid.X, roomCentroid.Y, 0), familySymbol, internalRoom.Level,
                                                           StructuralType.NonStructural);
            }
            trans2.Commit();
            //delete the temp file
            File.Delete(familyFilePath);
            //cast to Dynamo type for output and location updating (if necessary)
            famInstance = internalFam.ToDSType(true);
            if (fileFound)
            {
                famInstance.SetLocation(locationPoint);
            }
            //returns the outputs
            var outInfo = new Dictionary <string, object>
            {
                { "familyInstance", famInstance }
            };

            return(outInfo);
        }