.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

WblockCloneObjects() causes System.AccessViolationException

6 REPLIES 6
Reply
Message 1 of 7
autocart
1763 Views, 6 Replies

WblockCloneObjects() causes System.AccessViolationException

Hi forum,

As mentioned in the subject line, the database-method WblockCloneObjects() keeps causing a System.AccessViolationException with me.

I try to copy the contents (entities) from a xref-database into my current space (which is open in the editor). Therefore I create a new DB and readDwgFile the xref-dwg-file in.
The whole thing is in a foreach loop. Unfortunately it is pretty unpredictory when it occurs. Sometimes it comes sooner, sometimes later. Sometimes the code works without any problems.
At the moment I tried to call WblockCloneObjects() outside of any transaction (therefore the somehow many transactions) but it did not help.
(I am sure the general coding-style could be better too. Please forgive Smiley Happy)

Any ideas? Please help!!! Thx.

 

            try
            {
                foreach (ObjectId oId in blkDefsXref)
                {
                    // Open xrefDb and copy its modelspace entities for each reference to the current space
                    //
                    // Load Xref into sideDb
                    String xrefPath;
                    BlockTableRecord btr;

                    using (Transaction curTr = curDb.TransactionManager.StartTransaction())
                    {
                        btr = curTr.GetObject(oId, OpenMode.ForRead) as BlockTableRecord;
                        xrefPath = btr.PathName;
                        curTr.Commit();
                    }

                    if (xrefPath.Contains(".\\") || !xrefPath.Contains("\\"))
                        xrefPath = HostApplicationServices.Current.FindFile(xrefPath, curDb, FindFileHint.XRefDrawing);
                    Database sourceDb = new Database(false, true);
                    using (sourceDb)
                    {
                        sourceDb.ReadDwgFile(xrefPath, System.IO.FileShare.Read, true, "");

                        ObjectIdCollection idsEntitiesToCopy = new ObjectIdCollection();
                        using (Transaction sourceTr = sourceDb.TransactionManager.StartTransaction())
                        {
                            // Get the entities which are to be cloned:
                            // Open the source block table record Model space for read
                            BlockTable sourceBlkTbl = sourceTr.GetObject(sourceDb.BlockTableId, OpenMode.ForRead) as BlockTable;
                            BlockTableRecord modelspace_source = sourceTr.GetObject(sourceBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord;
                            //
                            // Make objectIdCollection to be cloned (of entities in source modelspace)
                            foreach (ObjectId tmpOId in modelspace_source)
                            {
                                DBObject tmpO = sourceTr.GetObject(tmpOId, OpenMode.ForRead);
                                // The next line (if ...) filters the entites (typFilter_EntityClass was defined outside of the try-catch)
                                if (tmpO.GetType() == typFilter_EntityClass || tmpO.GetType().IsSubclassOf(typFilter_EntityClass))
                                    idsEntitiesToCopy.Add(tmpOId);
                            }
                            sourceTr.Commit();
                        }

                        // Finally clone the entities for each reference of the current idBlkDef:
                        ObjectIdCollection oids = getReferencesOfBlockInCurrentSpace(btr);
                        foreach (ObjectId xrefId in oids)
                        {
                            using (Transaction curTr = curDb.TransactionManager.StartTransaction())
                            {
                                BlockReference xrefReference = curTr.GetObject(xrefId, OpenMode.ForRead) as BlockReference;
                                // tranlate the entities to be copied so that they will be optically positioned on the same location in the drawing as the entities in the reference
                                refOcsOrigin = xrefReference.Position;
                                refOcsXaxis = xrefReference.GetPlane().GetCoordinateSystem().Xaxis;
                                refOcsYaxis = xrefReference.GetPlane().GetCoordinateSystem().Yaxis;
                                refOcsZaxis = xrefReference.Normal;
                                refRotation = xrefReference.Rotation;
                                refXscale = xrefReference.ScaleFactors.X;

                                using (Transaction sourceTr = sourceDb.TransactionManager.StartTransaction())
                                {
                                    foreach (ObjectId entityOId in idsEntitiesToCopy)
                                    {
                                        Entity ent = sourceTr.GetObject(entityOId, OpenMode.ForWrite) as Entity;
                                        if (refXscale < 0)
                                            ent.TransformBy(Matrix3d.Mirroring(new Plane(sourceDb.Insbase, new Vector3d(0, 1, 0), new Vector3d(0, 0, 1))));
                                        ent.TransformBy(Matrix3d.Rotation(refRotation, new Vector3d(0, 0, 1), sourceDb.Insbase));
                                        ent.TransformBy(Matrix3d.AlignCoordinateSystem(sourceDb.Insbase, new Vector3d(1, 0, 0), new Vector3d(0, 1, 0), new Vector3d(0, 0, 1),
                                            refOcsOrigin, refOcsXaxis, refOcsYaxis, refOcsZaxis));
                                    }
                                    sourceTr.Commit();
                                }
                                curTr.Commit();
                            }

                            sourceDb.WblockCloneObjects(idsEntitiesToCopy, curDb.CurrentSpaceId, new IdMapping(), DuplicateRecordCloning.Replace, false);

                            // undo the translation
                            using (Transaction sourceTr = sourceDb.TransactionManager.StartTransaction())
                            {
                                foreach (ObjectId entityOId in idsEntitiesToCopy)
                                {
                                    Entity ent = sourceTr.GetObject(entityOId, OpenMode.ForWrite) as Entity;
                                    ent.TransformBy(Matrix3d.AlignCoordinateSystem(refOcsOrigin, refOcsXaxis, refOcsYaxis, refOcsZaxis,
                                        sourceDb.Insbase, new Vector3d(1, 0, 0), new Vector3d(0, 1, 0), new Vector3d(0, 0, 1)));
                                    ent.TransformBy(Matrix3d.Rotation(refRotation * -1, new Vector3d(0, 0, 1), sourceDb.Insbase));
                                    if (refXscale < 0)
                                        ent.TransformBy(Matrix3d.Mirroring(new Plane(sourceDb.Insbase, new Vector3d(0, 1, 0), new Vector3d(0, 0, 1))));
                                }
                                sourceTr.Commit();
                            }
                        }
                    }
                }
            }
            catch (System.Exception e)
            {
                ed.WriteMessage("\nError in else (xref):\n" + e.ToString());
                return;
            }

 

6 REPLIES 6
Message 2 of 7
Alfred.NESWADBA
in reply to: autocart

Hi,

 

first: do you have the code-line, where the code crashes? Or does AutoCAD bring you the exception after passing the whole code?

A few ideas:

1) When I interpret your code correctly, you will have a problem, when your XRef is placed more than once within the ModelSpace. You do (within the part "Finally clone the entities for each reference of the current idBlkDef") multiply set the TransformMatrix before placing the objects on the ModelSpace, So having the XRef inserted 3 times, the TransformationMatrix of the last XRef wins.

2) Even when I don't read that correct, you do transform the objects in the XRef-DB ... I would not do that, do the transformation in the current database (with the already copied-objects, not with the source-objects).

3) my way of solving the issue (like binding XRef): create a Block(definition) and copy with WBlockCloneObjects the XRef-Objects not onto the ModelSpace of your current drawing, but directly into the new Block. Than you can insert this Block into the ModelSpace for every XRef-position and use the BlockTransformation of the XRef directly to the new BlockReference.

That would create less transformations (not every single entity has to be moved/scaled/rotated, one time the whole BlockReference, finished). And if you need the elements not in block-structure you can just explode the BlockReference at the end of your proggi.

 

HTH, - alfred -

------------------------------------------------------------------------------------
Alfred NESWADBA
Ingenieur Studio HOLLAUS ... www.hollaus.at ... blog.hollaus.at ... CDay 2024
------------------------------------------------------------------------------------
(not an Autodesk consultant)
Message 3 of 7
autocart
in reply to: Alfred.NESWADBA

Thx for the reply,

 

It always crashes at the lin:

sourceDb.WblockCloneObjects(....);

 

ad 1) I just apply the matrix to the content of the xref-modelspace. And only the content is copied. When I copy it - let's say 3 times - the matrix is applied and kept for each time seperately, since the xref is "taken apart". This works. I know from the times when the code runs to the end without crashing.

 

ad 2) Ok, I agree. However, even if I comment that section out completely, the crash still happens.

 

ad 3) Maybe that's better. I will have to try it out.

 

 

Message 4 of 7
autocart
in reply to: autocart

So, I tried the thingy with creating new block-definitions first. However, the same error occors when I try to copy the elements into the block-definition.

 

But I found something else:

I found out that the error comes when the drawings that I want to copy from (in this case the xrefs) are too large. For example when I run the proggi with an xref containing 4 lines it works ok. When I only change the xref to contain 624 lines and run the proggi in the host drawing again then I have the error.

Message 5 of 7
Alfred.NESWADBA
in reply to: autocart

Hi,

 

just to make sure, you also have checked with _AUDIT that the source-db is ok, is free from errors?

I don't really think, that 600 objects (as long as they are not complex like ACA- oder CIVIL3D-objects) could be a handicap. In the case you can reproduce this, I would do as next step to split it to 100-packages, then to 50-packages .... maybe you find with this way one specific element, that causes the crash (btw. do you have proxies in the source-db?).

 

Good luck, - alfred -

------------------------------------------------------------------------------------
Alfred NESWADBA
Ingenieur Studio HOLLAUS ... www.hollaus.at ... blog.hollaus.at ... CDay 2024
------------------------------------------------------------------------------------
(not an Autodesk consultant)
Message 6 of 7
autocart
in reply to: Alfred.NESWADBA

just found out that when I step through the code slowly (breakpoint and then manually) it works again.

But when I press the "continue" button too fast while debugging then it runs into the error again. *Ahhhhrrrghh*

Both with 624 elements.

Message 7 of 7
autocart
in reply to: autocart

ok, it seems I finally found the solution (after probably a week of delay):

The wrong part in
sourceDb.WblockCloneObjects(idsEntitiesToCopy, curDb.CurrentSpaceId, new IdMapping(), DuplicateRecordCloning.Replace, false);
is that I passed "new IdMapping()" directly to the calling of the method.
I MUST be defined outside first i.e. as

IdMapping idm = new IdMapping();

and then the method MUST be called with the variablename passed to it like this:

sourceDb.WblockCloneObjects(idsEntitiesToCopy, curDb.CurrentSpaceId, idm, DuplicateRecordCloning.Replace, false);

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost