In a circular reference drawing (A>B>C>A) how to find the link between C and A which makes the three drawing circular?

In a circular reference drawing (A>B>C>A) how to find the link between C and A which makes the three drawing circular?

Nikita_RAUTELA
Participant Participant
512 Views
12 Replies
Message 1 of 13

In a circular reference drawing (A>B>C>A) how to find the link between C and A which makes the three drawing circular?

Nikita_RAUTELA
Participant
Participant

I have 3 drawings A, B and C. I have nested the drawings as A>B, B>C, C>A, which makes the three in circular relation. when I open A, the structure is like A(root)>B>C(leaf), when I open C its like C>A>B, and similarly for B.
According to my understanding when a drawing having circular dependencies is opened, say A,  the circular reference is broken as a dialog pops up to continue opening the drawing(if ok, then the circular link is broken)A>B>C(*>A). I iterate from Root graphNode to the leaf but as soon as I reach the leaf the count for the out referencing is 0, which is not true as leaf is parent to the root(making it circular)(C>A). 
How can I get the link from C>A as the link between C and A is still maintained in other drawings(C>A>B)?
Is there any object that is the single source of truth for a drawing and that holds the information of wherever the drawing is referenced?

Currently I am using AcDbXrefGraphNode::out() method to get the outgoing references for the active drawing but unfortunately it does not include the circular reference. 
I tried the following too, but I am not sure if I am doing it correctly:

1. get the XREFBlockID from the active document using xrefBlockId()

2. Use the blocID in acdbOpenObject() to get AcDbBlockTableRecord, further I can get the BlockTable.I am not sure if this is the right method and what to do next.

 

Nikita_RAUTELA_0-1757336720091.png

Here BAS1, BAS2, BAS3 can be considered as A,B,C.

 

I am looking for a relevant AutoCAD API that can give me the indication that the drawing is circular.

More specifically my expectation is that I get the link between [the leaf] Drawing1 and [the root] Drawing2 , the circular link.
is there any property that conveys that the drawing had a circular link originally?

0 Likes
513 Views
12 Replies
Replies (12)
Message 2 of 13

imadHabash
Mentor
Mentor

Hi,

@Nikita_RAUTELA 

as much as i understand (hope so)...

Try from the External Reference palette to use  Tree View (F4)  option. (Upper right)

Imad Habash

EESignature

0 Likes
Message 3 of 13

pendean
Community Legend
Community Legend

@Nikita_RAUTELA Would this help you see your content relationships better? Activate it now. Show us the result.

pendean_0-1757339220356.png

 

0 Likes
Message 4 of 13

J-Porter
Collaborator
Collaborator

In your image you are setting the references up as overlays.  Therefore, you should not have any circular references.  

0 Likes
Message 5 of 13

Nikita_RAUTELA
Participant
Participant

@pendean @J-Porter @imadHabash thanks for the suggestions the result is as follows (but my expectation is not with the UI):

Nikita_RAUTELA_0-1757397253847.png

I am developing a program to travel through all the attached references. I am looking for a relevant AutoCAD API that can give me the indication that the drawing is circular.

More specifically my expectation is that I get the link between [the leaf] Drawing1 and [the root] Drawing2 , the circular link.
is there any property that conveys that the drawing had a circular link originally?

0 Likes
Message 6 of 13

BlackBox_
Advisor
Advisor

@Nikita_RAUTELA wrote:

I am developing a program to travel through all the attached references. I am looking for a relevant AutoCAD API that can give me the indication that the drawing is circular.

More specifically my expectation is that I get the link between [the leaf] Drawing1 and [the root] Drawing2 , the circular link.
is there any property that conveys that the drawing had a circular link originally?


You've not posted any code (in the .NET forum) for the program you're developing, so it's going to be hard for someone to offer advice. 

 

As a starting point, consider iterating each XREF using ReadDwgFile() with FileOpenMode.OpenForReadAndAllShare, and checking those for an XREF that matches your active document. 

 

Cheers


"How we think determines what we do, and what we do determines what we get."

Sincpac C3D ~ Autodesk Exchange Apps

0 Likes
Message 7 of 13

Nikita_RAUTELA
Participant
Participant

Currently I am using AcDbXrefGraphNode::out() method to get the outgoing references for the active drawing but unfortunately it does not include the circular reference. 
I tried the following too, but I am not sure if I am doing it correctly:

1. get the XREFBlockID from the active document using xrefBlockId()

2. Use the blocID in acdbOpenObject() to get AcDbBlockTableRecord, further I can get the BlockTable.

I am not sure if this is the right method and what to do next.

 

I am coding in native(c++) I am not sure if I can set FileOpenMode, but I will explore this as well

0 Likes
Message 8 of 13

pendean
Community Legend
Community Legend

@Nikita_RAUTELA As noted by @J-Porter I suspect your core issue is most likely having chosen this type of XREF (which you need to change as that option hides XREFs)

pendean_0-1757420749270.png

 

0 Likes
Message 9 of 13

J-Porter
Collaborator
Collaborator

"I am looking for a relevant AutoCAD API that can give me the indication that the drawing is circular."


Natively, there is nothing I can think of except the warning you get when you are about to create a circular xref.  And there are even ways to get around that warning.  Outside of that, you don't notice a circular xref until it's too late.  

 

I wish there was a way to manage control through the reference manager:  https://forums.autodesk.com/t5/civil-3d-ideas/update-request-to-the-reference-manager/idc-p/13724670...

 

 

 

0 Likes
Message 10 of 13

BlackBox_
Advisor
Advisor

@Nikita_RAUTELA wrote:

Currently I am using AcDbXrefGraphNode::out() method to get the outgoing references for the active drawing but unfortunately it does not include the circular reference. 
I tried the following too, but I am not sure if I am doing it correctly:

1. get the XREFBlockID from the active document using xrefBlockId()

2. Use the blocID in acdbOpenObject() to get AcDbBlockTableRecord, further I can get the BlockTable.

I am not sure if this is the right method and what to do next.

 

I am coding in native(c++) I am not sure if I can set FileOpenMode, but I will explore this as well


I understand that you're attempting to identify this within the active document scope - but that is insufficient (even in ARX) - as an XREF in the active document is effectively a copy of the source drawing (and mostly behaves as a block reference). 

 

An XREF does give you access to its source drawing, which can be opened as a side database - I work in Civil 3D, so I'm relegated to .NET - regardless, you'll need to open the XREFs as side database using AcDbDatabase::readDwgFile() (C++), then query that side DB for it's XREFs, filtering for any that match active document's path, to solve your circular reference query. 

 

Hope that makes more sense.

 

[Edit] - Oh! Don't forget to resolve any relative paths.


"How we think determines what we do, and what we do determines what we get."

Sincpac C3D ~ Autodesk Exchange Apps

0 Likes
Message 11 of 13

Nikita_RAUTELA
Participant
Participant

When I perform readDwgFile for the leaf drawing, I am able to get the xRefGraph and eventually its xRefGraphNode(the one I was looking for), but there is an issue while doing this, the status of the xrefNode is unresolved and it does not contain its DB. I tried to access the DB by further getting the BlockID from the xrefGraphNode but the DB there is that of the parent I suppose because the filename in it is that of the leaf drawing only.
Although, I can get the name of the Top Drawing from the leaf, this is still insufficient in my case, as path is not fetchable.
Am I doing something wrong or are the xref opened via readDwgFile's DB always in unresolved state?

0 Likes
Message 12 of 13

BlackBox_
Advisor
Advisor

@Nikita_RAUTELA wrote:

When I perform readDwgFile for the leaf drawing, I am able to get the xRefGraph and eventually its xRefGraphNode(the one I was looking for), but there is an issue while doing this, the status of the xrefNode is unresolved and it does not contain its DB. I tried to access the DB by further getting the BlockID from the xrefGraphNode but the DB there is that of the parent I suppose because the filename in it is that of the leaf drawing only.
Although, I can get the name of the Top Drawing from the leaf, this is still insufficient in my case, as path is not fetchable.
Am I doing something wrong or are the xref opened via readDwgFile's DB always in unresolved state?


You've not posted any code, so difficult for someone to see where you're stuck. 

 

Did you store HostApplicationServices.WorkingDatabase, then try {} setting side database current before calling ResolveXrefs() & GetHostDwgXrefGraph(), and finally {} set old database current again?

 

Never needed to use XrefGraph before, so I'm sure there's a way, but in some test code it was pretty easy to iterate side database's BlockTable to confirm status BlockTableRecord.IsFromExternalReference && !BlockTableRecord.IsFromOverlayReference (since an XREF as attachment is the only real circular reference). The code I have detects the nested circular reference in both B and C - which is technically correct, since they all XREF another as attachment and changing one of them from attachment to overlay would resolve - but will take more work to isolate the culprit to only being C.dwg (with A.dwg open in the editor, that is). 

 

HTH

 

                            using (Database sideDb = new Database(false, true))
                            {
                                sideDb.ReadDwgFile(path, FileOpenMode.OpenForReadAndAllShare, false, "");
                                sideDb.CloseInput(true);

                                using (Transaction tr = sideDb.TransactionManager.StartTransaction())
                                {
                                    BlockTable bt = (BlockTable)tr.GetObject(sideDb.BlockTableId, OpenMode.ForRead);
                                    foreach (ObjectId btrId in bt) // <-- replace with linq
                                    {
                                        BlockTableRecord btr = (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForRead);

                                        if (!btr.IsFromExternalReference || btr.IsFromOverlayReference) continue;

                                        ed.WriteMessage($"\n; xref: {btr.PathName}");
                                        if (PathsEqual(btr.PathName.ToUpper(), dwg.ToUpper())) // <-- Normalize paths
                                            ed.WriteMessage($"\n; circular xref found in: {path}");
                                    }
                                    tr.Commit();
                                }
                            }

 

 

 

 


"How we think determines what we do, and what we do determines what we get."

Sincpac C3D ~ Autodesk Exchange Apps

0 Likes
Message 13 of 13

Nikita_RAUTELA
Participant
Participant

I am suspecting that in your case, the drawing file is not opened in AutoCAD, coming from my observation when I open the drawing file in ACAD it shows a warning that the drawing has circular reference and do you still want to proceed, on proceeding I believe it resolves the circular links and then open the file, thus, I get the isCircularReference api  as  false. 
Nevertheless, I was able to get the filename so i managed to make my use case work, thanks a lot for all the help, much appreciated. I will definitely update if I stumble on some alternative that works.
Bets Regards!

0 Likes