Can't save boolean operation to disk.

Can't save boolean operation to disk.

Anonymous
Not applicable
1,234 Views
9 Replies
Message 1 of 10

Can't save boolean operation to disk.

Anonymous
Not applicable

Hi,

In the following routine, while cycling through all the entities, i delete some of them and i do a boolean operation for some of them.

At the end I save the drawing with a new name. When I open the drawing, the deleted entites are gone, as they should be, but the ones which went through the boolean operation are not modified. On the screen they look like the boolean operation was successful. If i save the drawing manually, they are saved correctly.

Should I do more than committing the transaction before saving the drawing?

Thank you.

Document acDoc = Application.DocumentManager.MdiActiveDocument;

            Editor ed = acDoc.Editor;

            Database acCurDb = acDoc.Database;

            // LOCK DOCUMENT BEFORE TRANSACTION
            using (DocumentLock docLock = acDoc.LockDocument())
            using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
            {
                // Open the Block table record for read
                ed.WriteMessage("\nDAP");
                BlockTable acBlkTbl;
                acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId,
                                                OpenMode.ForRead) as BlockTable;

                // Open the Block table record Model space for write
                BlockTableRecord acBlkTblRec;
                acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace],
                                                OpenMode.ForWrite) as BlockTableRecord;
                foreach (ObjectId id in acBlkTblRec)
                {

                    Solid3d entity = (Solid3d)acTrans.GetObject(id, OpenMode.ForWrite);
                    ObjectId intityId = entity.ObjectId;
                    Extents3d ext = entity.GeometricExtents;

                    
                    if ((ext.MaxPoint.X < tileMin.X)||
                        (ext.MinPoint.X>tileMax.X)||
                        (ext.MaxPoint.Y<tileMin.Y)||
                        (ext.MinPoint.Y>tileMax.Y)
                        )//if outside
                    {
                        //delete entity
                        entity.Erase(true);
                    }
                    else if (!((ext.MinPoint.X > tileMin.X) && (ext.MinPoint.Y > tileMin.Y) &&
                        (ext.MaxPoint.X < tileMax.X) && (ext.MaxPoint.Y < tileMax.Y)))//else if not completely inside
                    {
                        // start creating box
                        using (var box = new Solid3d())
                        {
                            box.CreateBox(250.0, 250, 800.0);
                            box.TransformBy(Matrix3d.Displacement(new Vector3d(tileMin.X+125.0, tileMin.Y+125.0, 0.0)));
                            entity.BooleanOperation(BooleanOperationType.BoolIntersect, box);
                        }
                        // end creating box
                    }
                }

                // Save the new objects to the database
                acTrans.Commit();
            }
            ed.WriteMessage(cale + deTaiat + "\\" + deTaiat + "_" + quarter[ct] + "_" + sixteen[4 * ct + ct1] + "_SOLID.dwg");
            acCurDb.SaveAs(cale + deTaiat + "\\" + deTaiat + "_" + quarter[ct] +"_" + sixteen[4*ct+ct1]+ "_SOLID.dwg", DwgVersion.Current);
0 Likes
1,235 Views
9 Replies
Replies (9)
Message 2 of 10

_gile
Consultant
Consultant

Does the following snippet works for you? (run it in an empty drawing)

If so, you should search the context differences between this code and yours.

 

        [CommandMethod("TEST", CommandFlags.Session)]
        public static void Test()
        {
            var docs = Application.DocumentManager;
            var doc = docs.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;
            using (doc.LockDocument())
            using (var tr = db.TransactionManager.StartTransaction())
            {
                var cs = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
                var sphere = new Solid3d();
                sphere.CreateSphere(7.0);
                sphere.TransformBy(Matrix3d.Displacement(new Vector3d(5.0, 5.0, 5.0)));
                cs.AppendEntity(sphere);
                tr.AddNewlyCreatedDBObject(sphere, true);
                using (var box = new Solid3d())
                {
                    box.CreateBox(10.0, 10.0, 10.0);
                    box.TransformBy(Matrix3d.Displacement(new Vector3d(5.0, 5.0, 5.0)));
                    sphere.BooleanOperation(BooleanOperationType.BoolIntersect, box);
                }
                    tr.Commit();
            }
            db.SaveAs(@"C:\Temp\BooleanTest.dwg", DwgVersion.Current);
            docs.Open(@"C:\Temp\BooleanTest.dwg");
            docs.MdiActiveDocument.SendStringToExecute("_-view _seiso\n", false, false, false);
        }


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 3 of 10

Anonymous
Not applicable

There are many minor differences between the codes, so i changed gradually your code to see if I end up getting the same error.

First i did the boolean operation between an existing sphere and a newly generated box. I ran Test in a drawing that was containing already the sphere. 

Then, when I tried to open the drawing automatically, then do the boolean operation, i got the same problem with the boolean operation not being saved.

It's definitely something i'm not doing just before saving.

I attached the drawing that contains the sphere.

 

Thank you for your help so far.

 

Please see attached code:

 

[CommandMethod("TEST", CommandFlags.Session)]
        public static void Test()
        {
            var docs = Application.DocumentManager;
            string file = "C:\\Temp\\BooleanTest1.dwg";
            if (File.Exists(file))
            {
                Document almeu = docs.Open(file, false);
                docs.MdiActiveDocument = almeu;
                string drName = Path.GetFileName(almeu.Name);
            }
            else
            {
                docs.MdiActiveDocument.Editor.WriteMessage("File " + file + " does not exist.");
            }
            var doc = docs.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;
            using (doc.LockDocument())
            using (var tr = db.TransactionManager.StartTransaction())
            {
                var cs = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
                foreach (ObjectId id in cs)
                {
                    Solid3d entity = (Solid3d)tr.GetObject(id, OpenMode.ForWrite);
                    //var sphere = new Solid3d();
                    //sphere.CreateSphere(7.0);
                    //sphere.TransformBy(Matrix3d.Displacement(new Vector3d(5.0, 5.0, 5.0)));
                    //cs.AppendEntity(sphere);
                    //tr.AddNewlyCreatedDBObject(sphere, true);
                    using (var box = new Solid3d())
                    {
                        box.CreateBox(10.0, 10.0, 10.0);
                        box.TransformBy(Matrix3d.Displacement(new Vector3d(5.0, 5.0, 5.0)));
                        entity.BooleanOperation(BooleanOperationType.BoolIntersect, box);
                    }
                }
                tr.Commit();
            }
            db.SaveAs("C:\\Temp\\BooleanTest.dwg", DwgVersion.Current);

            docs.Open("C:\\Temp\\BooleanTest.dwg");
            docs.MdiActiveDocument.SendStringToExecute("_-view _seiso\n", false, false, false);
        }

 

 

0 Likes
Message 4 of 10

_gile
Consultant
Consultant

I just tested your code and it worked fine.

Which version of AutoCAD are you using?



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 5 of 10

Anonymous
Not applicable

2019 Vanilla AutoCAD.

0 Likes
Message 6 of 10

_gile
Consultant
Consultant

It works fine for me with 2019 Vanilla AutoCAD.

Perhaps some settings, but I cannot see which.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 7 of 10

Anonymous
Not applicable

I discovered that it's a visualisation issue probably.

The boolean operation is saved, but i't not visible in 2d wireframe. any other visual style shows the objects as they should be.

Also, even if I am in 2d wireframe, if I orbit, it looks the right way, with the trimmed solids.

Can you open the attached file to see how it looks?

Thank you.

0 Likes
Message 8 of 10

_gile
Consultant
Consultant

That's what I see when I open the file:

TT.png



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 9 of 10

Anonymous
Not applicable

So the issue with is my computer. The code works perfectly.

when i open the drawing, it looks like this:

Capture.PNG

If i orbit, it looks like this:

1.png

When i exit orbit, it looks like this:

2.png

I'll have to figure out what's wrong with my autocad, but i can use the routine as is.

Thank you so much for all your help!

 

0 Likes
Message 10 of 10

Anonymous
Not applicable

The solution was a workaround.

Instead of using database.saveas, the routine is copying the original file, runs on the new file and uses doc.closeandsave.

This way the weird display doesn't happen anymore.

0 Likes