DivideParts according to a grid

DivideParts according to a grid

franjavigarciavalencia
Enthusiast Enthusiast
1,873 Views
6 Replies
Message 1 of 7

DivideParts according to a grid

franjavigarciavalencia
Enthusiast
Enthusiast

Hello, I am trying to divide a Floor element into several Parts using a grid that will come from an external file but I am having trouble getting it to work. Any and all help would be appreciated.

 

The grid file is a .txt with the starting and ending point of each line, forming a grid.

 

Here's the code I have so far:

 

 

// Returns the Parts' ElementIds
public List<ElementId> DivideElement(Document doc, Element floor, string grid_file)
        {
            List<ElementId> pieces = new List<ElementId>();

            // Read coordinates from grid_file
            string path = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), grid_file);
            // Method which returns tuples of origin and end coordinates for each grid line
            List<Tuple<XYZ, XYZ>> grid = CreateGridLines(path);

            IList<ElementId> to_divide = new List<ElementId>(1);
            to_divide.Add(floor.Id);

            // Grid
            IList<Curve> curveArray = new List<Curve>();

            foreach (Tuple<XYZ,XYZ> line_coord in grid)
            {
                Line line = Line.CreateBound(line_coord.Item1, line_coord.Item2);
                curveArray.Add(line);
            }

            // Intersection ElementIds
            IList<ElementId> intersectionElementIds = new List<ElementId>();


            Frame frame = new Frame();
            Plane plane = Plane.Create(frame);
            SketchPlane divisionSketchPlane = SketchPlane.Create(doc, plane);

            // commit curve array and plane
            doc.Regenerate();

            PartUtils.DivideParts(doc, to_divide, intersectionElementIds, curveArray, divisionSketchPlane.Id);

            // get all associated parts
            pieces = PartUtils.GetAssociatedParts(doc, floor.Id, true, true).ToList();

            divisionSketchPlane.Dispose();

            doc.Regenerate();

            return pieces;
        }

 

 

Thanks in advance.

0 Likes
Accepted solutions (1)
1,874 Views
6 Replies
Replies (6)
Message 2 of 7

jeremytammik
Autodesk
Autodesk

You are not adding any elements to `intersectionElementIds`. It remains empty.

  



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

0 Likes
Message 3 of 7

franjavigarciavalencia
Enthusiast
Enthusiast

What should I add? The curves do not have an ElementId that I can use. I have tried Curve.Reference.ElementId to no avail.

 

Thanks.

0 Likes
Message 4 of 7

RPTHOMAS108
Mentor
Mentor

My understanding from UI functionality is that you can divide by either datum elements (intersectingReferenceIds) or by sketch lines (curveArray) or by a combination of both.

 

So logically if API functionality is similar one of the arguments is optional. In your case since you are adding grid elements you can add the ElementIds for these to intersectingReferenceIds and leave the curve array empty. You may need to regenerate after adding the grids. If this doesn't work then perhaps there is something wrong in terms of API functionality or what you are doing.

Do the grid lines you draw appear correctly when you comment out the other code aspects?

 

Seems odd that this method is not overloaded given the ways you can divide parts in the UI i.e. why do you need a sketch plane if you are dividing by datum elements such as grids or levels only?

Message 5 of 7

franjavigarciavalencia
Enthusiast
Enthusiast

Okay I fixed it.

The problem was that I was passing a Floor as an Element and it needed to be turned into a Part first, even if it is a one layer element.

 

I added :

PartUtils.CreateParts(doc, to_divide);
doc.Regenerate();

ICollection<ElementId> parts = PartUtils.GetAssociatedParts(doc, floor.Id, false, false);

 

And passed parts to DivideParts:

PartUtils.DivideParts(doc, parts, intersectionElementIds, curveArray, divisionSketchPlane.Id);

 

Also I changed the grid creation and instead of passing it through the curveArray, I created actual Grid elements and passed them as intersectionElementIds. But I think it should work either way.

 

Thanks for the help.

0 Likes
Message 6 of 7

jeremytammik
Autodesk
Autodesk

Would you like to share the complete method for the working solution, plus a code snippet showing the calling context to see where the arguments come from? That would make it easier for others to reuse, in case of need. Thank you!

 



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

Message 7 of 7

franjavigarciavalencia
Enthusiast
Enthusiast
Accepted solution

Sure, here it is. The Main snippet is quite simple but it should give enough context.

 

 

 

void Main (ExternalCommandData commandData)
{

    UIApplication uiapp = commandData.Application;
    UIDocument uidoc = uiapp.ActiveUIDocument;
    Document doc = uidoc.Document;

    List<ElementId> totalpieces = new List<ElementId>();

    FilteredElementCollector collector_floors = new 
    FilteredElementCollector(doc).OfClass(typeof(Floor));

    using (Transaction t = new Transaction(doc, "divide floors"))
            {
                t.Start();

                foreach (Element e in collector_floors )
                {
                    totalpieces.AddRange(DivideElement(doc, e, "grid.txt"));
                }

                t.Commit();
            }
}



public List<ElementId> DivideElement(Document doc, Element floor, string grid_file)
        {
            // Read .txt coordinates
            string path = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), grid_file);
            List<Tuple<XYZ, XYZ>> grid = CreateGridLines(path);

            // create part from floor
            IList<ElementId> to_divide = new List<ElementId>(1);
            to_divide.Add(floor.Id);
            PartUtils.CreateParts(doc, to_divide);

            // empty curve array
            IList<Curve> curveArray = new List<Curve>();

            // list of Grid elements which will define the division
            IList<ElementId> intersectionElementIds = new List<ElementId>();
            
            // create grids from the .txt coords
            foreach (Tuple<XYZ,XYZ> line_coord in grid)
            {
                Line line = Line.CreateBound(line_coord.Item1, line_coord.Item2);
                Grid newgrid = Grid.Create(doc, line);
                intersectionElementIds.Add(newgrid.Id);
            }

            // default SketchPlane 
            Frame frame = new Frame();
            Plane plane = Plane.Create(frame);
            SketchPlane divisionSketchPlane = SketchPlane.Create(doc, plane);

            // Commit grids, plane and part
            doc.Regenerate();

            // get the part created from the floor
            ICollection<ElementId> parts = PartUtils.GetAssociatedParts(doc, floor.Id, false, false);

            PartUtils.DivideParts(doc, parts, intersectionElementIds, curveArray, divisionSketchPlane.Id);
            divisionSketchPlane.Dispose();

            // commit division
            doc.Regenerate();

            // get parts divided from the first part created from the original floor
            List<ElementId> pieces = PartUtils.GetAssociatedParts(doc, parts.First(), true, true).ToList();


            return pieces;
        }

 

 

 

0 Likes