[Revit API] Converts a "Revit Elements" to solids and creates a family.

[Revit API] Converts a "Revit Elements" to solids and creates a family.

Anonymous
Not applicable
6,309 Views
4 Replies
Message 1 of 5

[Revit API] Converts a "Revit Elements" to solids and creates a family.

Anonymous
Not applicable

Thank you for reading first.
What I'm trying to do is...
I'm going to make the "Revit Elements" into a single solid and write it in "Revit Family".

( The reason I do this is to control the generated solids.     Please refer to the picture!! )

Please help me.

 

Modifiable Object.PNG

 

#region Namespaces
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;
#endregion

namespace RibbonButton
{
    [Transaction(TransactionMode.Manual)]
    public class Commend : IExternalCommand
    {
        #region
        string DirSearch(string start_dir, string filename_pattern)
        {
            foreach (string d in Directory.GetDirectories(
              start_dir))
            {
                foreach (string f in Directory.GetFiles(
                  d, filename_pattern))
                {
                    return f;
                }

                string f2 = DirSearch(d, filename_pattern);

                if (null != f2)
                {
                    return f2;
                }
            }
            return null;
        }
        #endregion
        public UIDocument ActiveUIDocument { get; private set; }

        public Result Execute(
            ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            UIApplication uiapp = commandData.Application;
            UIDocument uidoc = uiapp.ActiveUIDocument;
            Autodesk.Revit.ApplicationServices.Application app = uiapp.Application;
            Document doc = uidoc.Document;

            // Code Start ↓

            // Element selection
            IList<Reference> selectedConduits = uidoc.Selection.PickObjects(ObjectType.Element);


            // Solid Union
            Solid union = null;

            foreach (var item in selectedConduits)
            {
                SolidGeometry solidgeo = item as Solid;

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

                    if (null != solid
                      && 0 < solid.Faces.Size)
                    {
                        if (null == union)
                        {
                            union = solid;
                        }
                        else
                        {
                            union = BooleanOperationsUtils.ExecuteBooleanOperation(union, solid,BooleanOperationsType.Union);
                        }
                    }
                }
            }

            // Create Generic Model
            using (Transaction trans = new Transaction(doc, "Transaction")) 
            {
                try
                {
                    trans.Start();
                    DirSearch(app.FamilyTemplatePath, "Metric Generic Model.rft");
                    trans.Commit();
                }
                catch { }
            }

            // Code End ↑

            return Result.Succeeded;
        }
    }
}

 

0 Likes
Accepted solutions (3)
6,310 Views
4 Replies
Replies (4)
Message 2 of 5

jeremytammik
Autodesk
Autodesk
Accepted solution

You can easily retrieve all the element solids and convert them to a DirectShape element.

  

https://thebuildingcoder.typepad.com/blog/2015/11/flatten-all-elements-to-directshape.html

  

The DirectShape element can be used in a family definition to define the required family.

  



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 3 of 5

Revitalizer
Advisor
Advisor
Accepted solution

Hi Jeremy,

 

DirectShape cannot be edited by the user, so FreeFormElement is the right sort of element.

FreeFormElement.Create(doc, solid) - and you are done.

 

 

Rudi




Rudolf Honke
Software Developer
Mensch und Maschine





Message 4 of 5

Anonymous
Not applicable

First of all, thank you for your reply.  

But there is a problem changing the type, so please do it again.

 

#region Namespaces
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;
#endregion

namespace RibbonButton
{
    [Transaction(TransactionMode.Manual)]
    public class Commend : IExternalCommand
    {
        public Result Execute(
            ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            UIApplication uiapp = commandData.Application;
            UIDocument uidoc = uiapp.ActiveUIDocument;
            Autodesk.Revit.ApplicationServices.Application app = uiapp.Application;
            Document doc = uidoc.Document;

            // Code Start ↓

            // Element selection
            IList<Reference> selectelem = uidoc.Selection.PickObjects(ObjectType.Element);

            List<Element> elems = new List<Element>();

            // I don't know how to convert from reference to element.
            foreach (Element elem in selectelem)
            {
                elems.Add(selectelem as Element);
            }


            // Solid Union
            Solid union = GetTargetSolids(elems);
            


            // Create Generic Model
            using (Transaction trans = new Transaction(doc, "Transaction"))
            {
                try
                {
                    trans.Start();
                    FreeFormElement.Create(doc, union);
                    trans.Commit();
                }
                catch { }
            }

            // Code End ↑

            return Result.Succeeded;
        }
        public static IList<Solid> GetTargetSolids(Element element)
        {
            List<Solid> solids = new List<Solid>();


            Options options = new Options();
            options.DetailLevel = ViewDetailLevel.Fine;
            GeometryElement geomElem = element.get_Geometry(options);
            foreach (GeometryObject geomObj in geomElem)
            {
                if (geomObj is Solid)
                {
                    Solid solid = (Solid)geomObj;
                    if (solid.Faces.Size > 0 && solid.Volume > 0.0)
                    {
                        solids.Add(solid);
                    }
                    // Single-level recursive check of instances. If viable solids are more than
                    // one level deep, this example ignores them.
                }
                else if (geomObj is GeometryInstance)
                {
                    GeometryInstance geomInst = (GeometryInstance)geomObj;
                    GeometryElement instGeomElem = geomInst.GetInstanceGeometry();
                    foreach (GeometryObject instGeomObj in instGeomElem)
                    {
                        if (instGeomObj is Solid)
                        {
                            Solid solid = (Solid)instGeomObj;
                            if (solid.Faces.Size > 0 && solid.Volume > 0.0)
                            {
                                solids.Add(solid);
                            }
                        }
                    }
                }
            }
            return solids;
        }
    }
}

 

Message 5 of 5

Revitalizer
Advisor
Advisor
Accepted solution

Hi,

 

you only can create FreeFormElements in Family context.

 

Please see "CreateNegativeBlockCommand.cs" in the SDK for reference.

(It's in the FreeFormElement folder.)

 

There you can see how to create a family document from template file etc.

 

Revitalizer




Rudolf Honke
Software Developer
Mensch und Maschine





0 Likes