Temporary Transaction Trick Exception

Temporary Transaction Trick Exception

Anonymous
Not applicable
3,195 Views
9 Replies
Message 1 of 10

Temporary Transaction Trick Exception

Anonymous
Not applicable

Hi,

I'm trying to use a trick of transactions. I remove everything from the wall and check the intersection of the edge of the wall and the line from the side of the room. But I have an error when working with

ICollection <ElementId> generatingElementIds =    wall.GetGeneratingElementIds (edges [0]);

An unhandled exception of type 'System.AccessViolationException' occurred in RevitDBAPI.dll
Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

What am I doing wrong?

 

  SetComparisonResult intersectionPoint = SetComparisonResult.Disjoint;
 using (Transaction ff=new Transaction(doc,"Get intersections"))
      {
             ff.Start();
                                 
 using (SubTransaction deleteTransaction = new SubTransaction(doc))
        {
            deleteTransaction.Start();

              if (idsFamilyInstance.Count > 0)
                  {
                    ICollection<Autodesk.Revit.DB.ElementId> deletedIdSet = new List<ElementId>();
                    deletedIdSet = doc.Delete(idsFamilyInstance);

                    if (0 == deletedIdSet.Count)
                     {
                        throw new Exception("Deleting the selected elements in Revit failed.");
                     }
                 }
                   doc.Regenerate();

  Options optionswall = new Options();
  optionswall.ComputeReferences = true;
  GeometryElement geometryElement = wall.get_Geometry(optionswall);

     foreach (GeometryObject geometry in geometryElement)
          {

            Solid geomSolidwall = geometry as Solid;

            // Get the faces
            foreach (Face face in geomSolidwall.Faces)
               {
                  //  doc.Regenerate();
                  intersectionPoint = face.Intersect(line);
                  if (intersectionPoint != SetComparisonResult.Disjoint)
                     {
                        break;
                     }
                 }

                 }

                    deleteTransaction.RollBack();
                    doc.Regenerate();

             }
                ff.Commit();
             }

               if (intersectionPoint != SetComparisonResult.Disjoint)
                    {

                        ICollection<ElementId> generatingElementIds =
                        wall.GetGeneratingElementIds(edges[0]);
              foreach (ElementId generatingElementId in generatingElementIds)
                     {
                       Element wallfromgenerating = doc.GetElement(generatingElementId);
                              if (wallfromgenerating is FamilyInstance)
                                 {

                                  }
                }

 

0 Likes
Accepted solutions (1)
3,196 Views
9 Replies
Replies (9)
Message 2 of 10

jeremytammik
Autodesk
Autodesk

I cannot read your code due to the random indentation.

 

That makes it hard for me to tell how the transactions are nested.

 

All I can say off-hand is that the call to the constructor here (using `new`) is totally superfluous, because the list is re-created anyway by the Delete method: 

 

  ICollection<ElementId> deletedIdSet = new List<ElementId>();
  deletedIdSet = doc.Delete(idsFamilyInstance);

 

Cheers,

 

Jeremy

 



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

0 Likes
Message 3 of 10

Anonymous
Not applicable

I apologize for the indentation, I was in a hurry. Now I have slightly corrected the code. After I applied the temporary transaction trick, I get an exception at the time of the ICollection <ElementId> generatingElementIds =
                                             wall.GetGeneratingElementIds (edges [0]);
Before the application of transactions, this exception did not appear. Perhaps the wall needs to be found inside the transaction?

           SetComparisonResult intersectionPoint = SetComparisonResult.Disjoint;

                                using (Transaction ff=new Transaction(doc,"sssss"))
                                {
                                    ff.Start();
                                 
                                using (SubTransaction deleteTransaction = new SubTransaction(doc))
                                {
                                    deleteTransaction.Start();

                                    if (idsFamilyInstance.Count > 0)
                                    {
                                        ICollection<Autodesk.Revit.DB.ElementId> deletedIdSet = doc.Delete(idsFamilyInstance);

                                        if (0 == deletedIdSet.Count)
                                        {
                                            throw new Exception("Deleting the selected elements in Revit failed.");
                                        }
                                    }
                                    doc.Regenerate();
                                    Options optionswall = new Options();
                                    optionswall.ComputeReferences = true;
                                    GeometryElement geometryElement = wall.get_Geometry(optionswall);
                                    foreach (GeometryObject geometry in geometryElement)
                                    {
                                        Solid geomSolidwall = geometry as Solid;
                                        // Get the faces
                                        foreach (Face face in geomSolidwall.Faces)
                                        {
                                            intersectionPoint = face.Intersect(line);
                                            if (intersectionPoint != SetComparisonResult.Disjoint)
                                            {
                                                break;
                                            }
                                        }

                                    }

                                    deleteTransaction.RollBack();

                                }//end subtransaction
                                    ff.Commit();
                                }//end transaction
                                if (intersectionPoint != SetComparisonResult.Disjoint)
                                    {
//on this line I get an exception
                                        ICollection<ElementId> generatingElementIds =
                                            wall.GetGeneratingElementIds(edges[0]);

                                    }
0 Likes
Message 4 of 10

Anonymous
Not applicable
I found a post in this forum in 2015, which looks at a similar problem: https://forums.autodesk.com/t5/revit-api-forum/accessviolationexception-on-new-getparameters-in-2015... Without a transaction my code works without exception, but it's worth changing the walls in the transaction and then returning everything back there is an exception
0 Likes
Message 5 of 10

RPTHOMAS108
Mentor
Mentor
Accepted solution

Where does edges[0] come from?

 

Why are you committing a transaction that contains a rolled back SubTransaction and little else. You probably don't need a SubTransaction. Just create a main Transaction, Delete your objects, Regenerate, get your info and then RollBack the Transaction (no Commit).

 

The error you are encountering occurs when a managed object no longer references a valid native object. e.g. when you use SpatialElementCalculator to get room boundaries, change the document with a transaction (which clears the cache of the geometry objects in the SpatialElementCalculator) but then you try and use an object from it as if it still exists. This might be your issue but you've not included the complete code showing the full lifecycle of the objects causing the problem, so it is hard to tell. Can check .IsValidObject on object deriving from Element (such as the Wall) but GeometryObjects don't derive from Element so don't have this property.

 

Message 6 of 10

Anonymous
Not applicable
I tried to use one transaction with a rollback. But when I use this method, I get errors Autodesk.Revit.Exceptions.InternalException
0 Likes
Message 7 of 10

Anonymous
Not applicable
var edges = FindEdges(edoor as FamilyInstance, e as Room).ToList(); These are the edges created by the door in the wall. If I'm using one transaction, I get an error: an exception of type 'Autodesk.Revit.Exceptions.InternalException' occurred in RevitAPI.dll but was not handled in user code Additional information: A managed exception was thrown in by Revit or by one of its external applications. This is the method of obtaining edges: private static IEnumerable FindEdges(FamilyInstance door, Room room) { var wall = (Wall)door.Host; return wall .get_Geometry(new Options { ComputeReferences = true }) .OfType() .SelectMany(x => x.Edges.OfType()) .Where(x => IsDoorEdge(x, door)) .Where(IsVerticalEdge) .Where(x => IsWallExteriorFaceEdge(x, wall.Orientation, room, door)); }
0 Likes
Message 8 of 10

Anonymous
Not applicable
In general, if I do not use the transaction at all, then everything works fine. If I use a transaction and rollback then a different error occurs after the transaction in the code. But if the code is debugged on the line, then there are no errors. but even if errors do not occur, the code does not work as correctly as before using the transaction. For example, points that used to belong to the room, when using the transaction room, for some reason do not belong
0 Likes
Message 9 of 10

Anonymous
Not applicable
I use a transaction inside a loop for each face of the room. Maybe this is the problem?
0 Likes
Message 10 of 10

Anonymous
Not applicable
Here is my code // Calculate a room's geometry and find its boundary faces SpatialElementGeometryCalculator calculator = new SpatialElementGeometryCalculator(doc); SpatialElementGeometryResults results = calculator.CalculateSpatialElementGeometry(room); Options opt2 = new Options(); opt2.ComputeReferences = true; Solid roomSolid = results.GetGeometry(); // get the solid representing the room's geometry Autodesk.Revit.DB.GeometryElement geomElemroom = e.get_Geometry(opt2); List listOfFace = new List(); List facesfororder = new List(); List listOfFaceWithoutExteriorWall = new List(); //Get walls fo determinate with changed walls List wallsForDetermine = new List(); SpatialElementBoundaryOptions optionswallForPoint2 = new SpatialElementBoundaryOptions(); optionswallForPoint2.SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.Finish; var walls = wallsForDetermine.Distinct(); Face faceOfRoomWithDoor = null; foreach (GeometryObject geomObj in geomElemroom) { Solid geomSolid = geomObj as Solid; List facesOfRoom = geomSolid.Faces.OfType().ToList(); foreach (Face faceinlist in facesOfRoom) { var resultsd = room.GetGeneratingElementIds(faceinlist); foreach (ElementId elementId in resultsd) { Element element = doc.GetElement(elementId); } BoundingBoxUV bboxUV = faceinlist.GetBoundingBox(); UV center = (bboxUV.Max + bboxUV.Min) / 2.0; XYZ normal = faceinlist.ComputeNormal(center); double u = bboxUV.Max.V/2 ; double v = bboxUV.Max.U/2; UV uv = new UV(v, u); XYZ location=null; if (faceinlist.IsInside(uv)) { location = faceinlist.Evaluate(center); } XYZ pt2 = location + 0.82 * normal; Line line = Line.CreateBound(location, pt2); SpatialElementBoundaryOptions optionswallForPoint = new SpatialElementBoundaryOptions(); optionswallForPoint.SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.Finish; foreach (IList boundSegList in room.GetBoundarySegments(optionswallForPoint)) { foreach (Autodesk.Revit.DB.BoundarySegment boundSeg in boundSegList) { Element elem = doc.GetElement(boundSeg.ElementId); Wall wall = elem as Wall; IntersectionResultArray intersectionResultArray = null; if (wall != null) { List idsFamilyInstance = new List(); Element elementFromWallForDelete; IList ids = wall.FindInserts(true, true, true, true); foreach (ElementId elementId in ids) { elementFromWallForDelete = doc.GetElement(elementId); if (elementFromWallForDelete is FamilyInstance) { idsFamilyInstance.Add(elementId); } } SetComparisonResult intersectionPoint = SetComparisonResult.Disjoint; using (Transaction ff=new Transaction(doc,"sssss")) { ff.Start(); if (idsFamilyInstance.Count > 0) { ICollection deletedIdSet = doc.Delete(idsFamilyInstance); if (0 == deletedIdSet.Count) { throw new Exception("Deleting the selected elements in Revit failed."); } } doc.Regenerate(); Options optionswall = new Options(); optionswall.ComputeReferences = true; GeometryElement geometryElement = wall.get_Geometry(optionswall); foreach (GeometryObject geometry in geometryElement) { Solid geomSolidwall = geometry as Solid; // Get the faces foreach (Face face in geomSolidwall.Faces) { // doc.Regenerate(); intersectionPoint = face.Intersect(line); if (intersectionPoint != SetComparisonResult.Disjoint) { break; } } } // doc.Regenerate(); ff.RollBack(); } if (intersectionPoint != SetComparisonResult.Disjoint) { ICollection generatingElementIds = null; foreach (KeyValuePair> wall1 in dictionary) { if (wall1.Key==wall.Id) { generatingElementIds = wall1.Value; } } foreach (ElementId generatingElementId in generatingElementIds) { Element wallfromgenerating = doc.GetElement(generatingElementId); if (wallfromgenerating is FamilyInstance) { faceOfRoomWithDoor = faceinlist; } } //Соседние стены стены, которые непостредственно примыкают //LocationCurve c = wall.Location as LocationCurve; //List neighbours = new List(); //for (int k = 0; k < 2; k++) //{ // neighbours.Add( c.get_ElementsAtJoin(k)); //} if (wall == wallOfDoor) { } if (!wall.Name.Contains("Нар") && wall != wallOfDoor) { listOfFaceWithoutExteriorWall.Add(faceinlist); } } } } } }
0 Likes