Cut wall make error

Cut wall make error

sonicer
Collaborator Collaborator
1,457 Views
4 Replies
Message 1 of 5

Cut wall make error

sonicer
Collaborator
Collaborator

Does someone know where is problem...

need cut wall with family void. But only if the results change the volume of the wall.

 

public void test(Document doc, IEnumerable<Element> w, IEnumerable<Element> e, ProgressBar pr)
        {


            double volumebefore;
            double volumeafter;

            foreach (Element q in w)
            {

                volumebefore = q.get_Parameter(BuiltInParameter.HOST_AREA_COMPUTED).AsDouble();
                foreach (Element s in e)
                {

                    try
                    {
                        using (Transaction tx = new Transaction(doc))
                        {
                            tx.Start("start transaction");
                            if (InstanceVoidCutUtils.CanBeCutWithVoid(q))
                            {
                                InstanceVoidCutUtils.AddInstanceVoidCut(doc, q, s);
                            }
                            // ElementIntersectsElementFilter cutintersectsfilter = new ElementIntersectsElementFilter(s, false);
                            // bool FamilyIntersectsWall = cutintersectsfilter.PassesFilter(doc, q.Id);
                            // if (FamilyIntersectsWall)


                            tx.Commit();
                            
                          
                                using (Transaction t1 = new Transaction(doc))
                                {
                                    t1.Start("start ");

                                    volumeafter = q.get_Parameter(BuiltInParameter.HOST_AREA_COMPUTED).AsDouble();


                                    if (volumebefore == volumeafter)
                                    {

                                        InstanceVoidCutUtils.RemoveInstanceVoidCut(doc, q, s);

                                    }
                                    else
                                    {
                                        volumebefore = volumeafter;
                                    }
                                    t1.Commit();
                                }
                            }
                            
                        }
                    }

                    catch { }



                    pr.Increment(1);
                }
            }
        }

still make error

 

The iterator cannot proceed due to changes made to the Element table in Revit's database (typically, this can be the result of an Element deletion).

0 Likes
Accepted solutions (1)
1,458 Views
4 Replies
Replies (4)
Message 2 of 5

FAIR59
Advisor
Advisor

I think, based on the error text you provided, that you pass a null value in list of walls or in the list of cutters. That can be solved by some error checking at the beginning of the method.

 

foreach (Element q in w)
            {
		if (q == null || !q.IsValidObject) continue;
		if (!InstanceVoidCutUtils.CanBeCutWithVoid(q)) continue;
                volumebefore = q.get_Parameter(BuiltInParameter.HOST_AREA_COMPUTED).AsDouble();
                foreach (Element s in e)
                {
                    if ( s ==null || !s.IsValidObject) continue;
                    if ( InstanceVoidCutUtils.InstanceVoidCutExists(q,s)) continue;
                    try
                    {
                        using (Transaction tx = new Transaction(doc))
                        {
                            tx.Start("start transaction");
                            InstanceVoidCutUtils.AddInstanceVoidCut(doc, q, s);
       			    tx.Commit();
			}

   

 

That will solve the issue, but leaves the question why it occurs.

 

Suggestions:

  • Are you creating the cutters in the same command?  If so, is the FamilySymbol Active?
  • try a document.Regenerate() before calling the method.
0 Likes
Message 3 of 5

sonicer
Collaborator
Collaborator

dont know where is problem ...if I cut the wall and then check if the volume is changing then I give same volume as before cut...

I used also doc.regenerate().

 

 

0 Likes
Message 4 of 5

FAIR59
Advisor
Advisor

Can you make the cut manually using the same cutting family?

If that's true, then I think the problem is somewhere in the rest of your code.

Using the same layout I made a command (Revit 2016) that works. { select 1 or more walls, 1 or more cutting instances and run command}

 

    [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
    public class Cmd_CutWalls : IExternalCommand
    {
        StringBuilder sb = new StringBuilder();
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            UIDocument uiDoc = commandData.Application.ActiveUIDocument;
            Document doc = uiDoc.Document;
            Autodesk.Revit.UI.Selection.Selection sel = commandData.Application.ActiveUIDocument.Selection;
            List<Element> walls = new List<Element>();
            List<Element> cutters = new List<Element>();
            foreach (ElementId id in sel.GetElementIds())
            {
                Element e = doc.GetElement(id);
                if (e is Wall) { walls.Add(e);}
                else { cutters.Add(e); }
            }

            double volumebefore = 0;
            double volumeafter =0 ;

            using (TransactionGroup tg = new TransactionGroup(doc, "cut walls"))
            {
                tg.Start();
                foreach (Element q in walls)
                {
                    if (q == null || !q.IsValidObject) continue;
                    sb.AppendLine(string.Format("wall  {0}", q.Id));
                    if (!InstanceVoidCutUtils.CanBeCutWithVoid(q)) continue;
                    volumebefore = q.get_Parameter(BuiltInParameter.HOST_AREA_COMPUTED).AsDouble();
                    foreach (Element s in cutters)
                    {
                        if (s == null || !s.IsValidObject) continue;
                        if (!InstanceVoidCutUtils.IsVoidInstanceCuttingElement(s))
                        {
                            sb.AppendLine("      instance is not family with unattached voids for cutting");
                            continue;
                        }
                        sb.AppendLine(string.Format("   cutter  {0}", s.Id));
                        if (InstanceVoidCutUtils.InstanceVoidCutExists(q, s))
                        {
                            sb.AppendLine("      instance is already cutting wall");
                            continue;
                        }
                        try
                        {
                            using (Transaction tx = new Transaction(doc))
                            {
                                tx.Start("start transaction");
                                InstanceVoidCutUtils.AddInstanceVoidCut(doc, q, s);
                                tx.Commit();
                            }
                            using (Transaction t1 = new Transaction(doc))
                            {
                                t1.Start("start ");
                                volumeafter = q.get_Parameter(BuiltInParameter.HOST_AREA_COMPUTED).AsDouble();
                                sb.AppendLine(string.Format("      volume_before: {0}    volume_after: {1}", volumebefore, volumeafter));
                                if (Math.Abs(volumebefore - volumeafter) < 0.0001)
                                {
                                    InstanceVoidCutUtils.RemoveInstanceVoidCut(doc, q, s);
                                    sb.AppendLine("        not cutting, cut removed");
                                }
                                else
                                {
                                    volumebefore = volumeafter;
                                    sb.AppendLine("        cut succeeded");
                                }
                                t1.Commit();
                            }
                        }
                        catch (Exception ex)
                        {
                            TaskDialog.Show("catch", ex.ToString());
                            return Result.Failed;
                        }
                    }
                    sb.AppendLine();
                }
                tg.Assimilate();
            }
            TaskDialog.Show("debug", sb.ToString());
            return Result.Succeeded;
        }
    }
0 Likes
Message 5 of 5

sonicer
Collaborator
Collaborator
Accepted solution

i found a problem ..

my mistake.

 

volumebefore = q.get_Parameter(BuiltInParameter.HOST_AREA_COMPUTED).AsDouble();

change to

volumebefore = q.get_Parameter(BuiltInParameter.HOST_VOLUME_COMPUTED).AsDouble();


0 Likes