Create Floor from CAD/ Import Instance

Anonymous

Create Floor from CAD/ Import Instance

Anonymous
Not applicable

Hi All, noob question, im kind'a stuck on creating floor from linked CAD or import instance, first problem is getting linked curves second is creating floor from that curves, any ideas or have similar code? Thanks.

 

        public void Command(UIDocument uidoc, Document doc)
        {
            Reference cad = uidoc.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element);

            
            if (cad != null)
            {
                Element element = doc.GetElement(cad);
                GeometryElement geoElement = element.get_Geometry(new Options());

                foreach (GeometryObject geoObject in geoElement)
                {
                    Curve curve = geoObject as Curve;                   
                }
            }
        }

    }
}
0 Likes
Reply
2,860 Views
7 Replies
Replies (7)

recepagah12
Advocate
Advocate

If you want to access an imported cad geometry, you should first explode the cad file. When you explode the cad file you will have access the objects individually. As an example, You want to create a floor. You should obtain floor lines and add them to a curve array. Then you can easily create a floor with Create Floor Method. I believe it is not possible to obtain a geometry from a cad file in Revit without exploding it. But maybe you can create 2 different transactions and in the first transaction, you explode the cad and obtain the geometry and rollback. In the second transaction, you create the floor and commit it. That is the only solution I see.

Also here is the how to use explode command via Revit API. Thanks to Jeremy Tammik.

DWG Explode

 

I hope this helps,

Recep.

 

0 Likes

Anonymous
Not applicable

Thanks, maybe this should work? the problem is floor method is expecting curveArray, is there a way to convert curves to CurveArray?

 

            Reference cad = uidoc.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element);

            //Delete Element
            if (cad != null)
            {
                Element element = doc.GetElement(cad);
                GeometryElement geoElement = element.get_Geometry(new Options());

                foreach (GeometryObject geoObject in geoElement)
                {
                    // Get the geometry instance which contains the geometry information
                    Autodesk.Revit.DB.GeometryInstance instance =
                            geoObject as Autodesk.Revit.DB.GeometryInstance;
                    if (null != instance)
                    {
                        GeometryElement instanceGeometryElement = instance.GetInstanceGeometry();
                        foreach (GeometryObject o in instanceGeometryElement)
                        {
                            // Try to find curves
                            Curve curve = o as Curve;

                            if (curve != null)

                            {
                                // Create Floor from Curves
                                Floor floor = doc.Create.NewFloor(curve, false);
    
                                
                            }
                        }
                    }
                }
            }
        }
    }
}

recepagah12
Advocate
Advocate

Curve Array is an Array class. So you can create an instance of it and add an item to it.

CurveArray curveArray = new CurveArray();
curveArray.Append(curve);

If you have any further question please don't hesitate to ask.

 

I hope this helps,

Recep.

0 Likes

Anonymous
Not applicable

Hi Thanks, So i come up with this, didn't get any error but also this didnt do anything,

 

            Reference cad = uidoc.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element);

            FilteredElementCollector collector = new FilteredElementCollector(doc);
            collector.OfClass(typeof(FloorType));
            FloorType floorType = collector.FirstElement() as FloorType;

            //TaskDialog.Show("x", floorType.Name);

            FilteredElementCollector levelcollector = new FilteredElementCollector(doc);
            levelcollector.OfClass(typeof(Level));
            Level level = levelcollector.FirstElement() as Level;
            //TaskDialog.Show("x", level.Name);

            XYZ normal = XYZ.BasisZ;
            CurveArray curveArray = new CurveArray();

            if (cad != null)
            {
                Element element = doc.GetElement(cad);

                // Get geometry element of the selected element
                Autodesk.Revit.DB.GeometryElement geoElement = element.get_Geometry(new Options());

                // Get geometry object
                foreach (GeometryObject geoObject in geoElement)
                {
                    // Get the geometry instance which contains the geometry information
                    Autodesk.Revit.DB.GeometryInstance instance =
                           geoObject as Autodesk.Revit.DB.GeometryInstance;
                    if (null != instance)
                    {
                        GeometryElement instanceGeometryElement = instance.GetInstanceGeometry();
                        foreach (GeometryObject o in instanceGeometryElement)

                        //if (o.GetType() == typeof(Autodesk.Revit.DB.PolyLine))
                        if (o is Curve)
                        {
                              
                            curveArray.Append(o as  Curve);
                            //Curve curve = o as Curve;
                            Floor floor = doc.Create.NewFloor(curveArray, floorType, level, false);
                            
                            //DetailCurve detailCurve = doc.Create.NewDetailCurve(doc.ActiveView, curve);//<for Testing
  
                        }

                    }
                }
            }
        }

    }
}

any idea?

0 Likes

recepagah12
Advocate
Advocate

First, you said you want to obtain data from a cad file. As I said earlier you need to explode the CAD file to access its geometric data. Did you do this with Revit API or manually in UI. Later, In exploded CAD files geometry will never be a polyline. In Revit, you will those lines as a Model Line or Detail Line which you can specify later in the API. You should obtain these model lines and get their curves and add these curves to Curve Array. So you can create a floor from these lines. I suggest you explode CAD file manually this is easier. Also, don't forget curves have to be closed.

 

Suggested Workflow:

  1. Explode the CAD file.
  2. Select model lines  from exploded fie
  3. Obtain their curves
  4. Add to Curve Array
  5. Create the Floor.

If you have any further question, please don't hesitate to ask.

Have a good day,

Recep.

 

 

0 Likes

Anonymous
Not applicable

Thanks for your help, i think at this stage i cannot go any further. I'll leave it for now

0 Likes

Anonymous
Not applicable

im back 😉 so i somehow manage to get it to work, but for single polyline only,  any idea? i supposed i need to group them by layer? just not sure how to do that 😕 

 

Thanks.

zCapture.JPG

 

 

       public void Command(UIDocument uidoc, Document doc)
        {

            Reference cad = uidoc.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element);

            if (cad != null)
            {
                Element pickedelement = doc.GetElement(cad);

                FloorType floorType = new FilteredElementCollector(doc)
                .OfClass(typeof(FloorType))
                .First<Element>(e => e.Name.Equals("FLoor")) as FloorType;

                Level level = new FilteredElementCollector(doc)
                .OfClass(typeof(Level))
                .First<Element>(e => e.Name.Equals("Level 0")) as Level;


                CurveArray curveArray = new CurveArray();

                // Get geometry element of the selected element
                Autodesk.Revit.DB.GeometryElement geoElement = pickedelement.get_Geometry(new Options());
                // Get geometry object
                foreach (GeometryObject geoObject in geoElement)
                {
                    // Get the geometry instance which contains the geometry information
                    Autodesk.Revit.DB.GeometryInstance instance = geoObject as Autodesk.Revit.DB.GeometryInstance;
                    if (null != instance)
                        try
                        {
                            GeometryElement instanceGeometryElement = instance.GetInstanceGeometry();
                            foreach (GeometryObject geometryObject in instanceGeometryElement)
                                if (geometryObject.GetType() == typeof(Autodesk.Revit.DB.PolyLine))
                                {
                                    List<PolyLine> polyLine = new List<PolyLine>();
                                    PolyLine line = (PolyLine)geometryObject;
                                    polyLine.Add(line);

                                    foreach (PolyLine poly in polyLine)
                                    {
                                        IList<XYZ> ptsList = poly.GetCoordinates();
                                        XYZ normal = XYZ.BasisZ;

                                        int i;
                                        for (i = 0; i <= ptsList.Count - 2; i++)
                                        {
                                            Line lines = (Line.CreateBound(ptsList[i], ptsList[i + 1]));

                                            curveArray.Append(lines);

                                        }
                                        Floor floor = doc.Create.NewFloor(curveArray, floorType, level, false, normal);
                                    }
                                }
                        }
                        catch (Exception ex)
                        {
                            //TaskDialog.Show("X", ex.ToString());
                        }
                }
            }
        }
    }
}