Hi everybody,
I'm currently developing a tool to reload specific layer settings like color, lineweight etc. from an xref if there was changed after he was attached and VISRETAIN is on.
This works except the with the linetypes:
myLyTblRecNew.LinetypeObjectId = myLiTypRec.ObjectId
myLiTypRec.ObjectId is the Id of the right linetype in the xref (like XREF|DASHDOT) and myLyTblRecNew.LinetypeObjectId is still the Id from the old linetype (in my case XREF|HIDDEN) but this command didn't work. No exception or error, AutoCAD completly ignore this line.
I would like assign the current xref linetype to the xref layer as it is in the xref. How can I do that in via .net?
The single approach that works is to switch VISRETAIN off, reload the Xref and switch VISRETAIN on again like here:
myDb.Visretain = False myDb.ReloadXrefs(XrefIDS) myDb.Visretain = True
But I would like to do this without reload xref (because it's very slow and I lost all other layer properties).
Any idea is much appreciated.
Kind regards
Holger
I believe you can only use local objects to override dependent objects.
myLiTypRec.ObjectId would need to be (DASHDOT) not (XREF|DASHDOT)
If you think about it that would cause problems or the drawing would have to know every drawing it was referenced in to not allow the linetype to be purged.
If DASHDOT was removed from the XREF drawing then XREF|DASHDOT would be invalid in the drawing that referenced it.
Hi Jeff,
from my understanding the XREF|DASHDOT is stored in the local database because VSIRETAIN is on. It doesn't matter if the linetype is purged in the Xref. I have also the issue in the same drawing that I want to change the layer from XREF2|DASHDOT to XREF2|HIDDEN what is also not possible (and XREF2|DASHDOT was already purged in XREF2). This is realy a pitty because ReloadXrefs is so much slower than an ReadDwgFile.
best
Holger
I think you are facing similar problem as I described some time ago here
So far what I found out is: Two xref-dependant linetypes XREF|HIDDEN and XREF|DASHED could be xref-source file database resident or host database resident. I was able assigned xref-dependant linetypes stored in host database to layer properties.
Regards,
Richard
See the Link in Richard posts about Linetypes having different databases.
The xref layers are local to the referencing database and Visretain just tells AutoCAD when loading an Xref if 0 relaod normal if 1 keep any local changes to layers.
How can you purge DASHDOT from XREF2 if a Layer uses it.
So if no layers use linetype DASHDOT in XREF2 because its purged then no layer would exist that reference that drawing with XREF2|DASHDOT linetype?
If I am wrong and not understanding this could you please load up an example of a drawing XREF2 that does not contain DASHDOT and a drawing that references it that has XREF2|DASHDOT.
Are you wanting to change a layer's linetype in a xref drawing and it only reload that one change and keep all other overrides?
Scenario is: xref is attached into host drawing, but then later user will load new linetype into xref and assign this linetype to some layer.
I may be wrong but what I found out is that to make linetype local, xref has to be reloaded with VISREATIN=0 (but linetype must be assigned to some layer in xref)
But if you wanted to use VISREATIN=1 than create in xref NEW temporary layer with needed linetype, save xref and reload it. Even with VISRTAIN=1 linetype will become local in host drawing (then you have to clear temp layer in xref and host).
But with both methods you have to reload xref, unfortunatelly.
Thanks,
Richard
Hi Holger / Jeff / Richard,
Sorry, if I misunderstood the problem, but I think it should be possible to reset the linetype as in this code snippet.
[CommandMethod("ResetLayer")] public void ResetLayerSettings() { Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; if (db.Visretain == false) { ed.WriteMessage("\nVISRETAIN is 0 Changes to layer setting will be reset by a reload of Xref."); return; } PromptResult pr = ed.GetString("\nEnter variable name: "); if (pr.Status != PromptStatus.OK) return; String layerName = pr.StringResult; XrefGraph xg = db.GetHostDwgXrefGraph(false); using (Transaction tr = db.TransactionManager.StartTransaction()) { LayerTable layerTable = tr.GetObject(db.LayerTableId, OpenMode.ForRead) as LayerTable; LinetypeTable lineTypeTable = tr.GetObject(db.LinetypeTableId, OpenMode.ForRead) as LinetypeTable; if (layerTable.Has(layerName)) { LayerTableRecord layerTableRec = tr.GetObject(layerTable[layerName], OpenMode.ForWrite) as LayerTableRecord; if (layerTableRec.IsDependent || layerName.Contains("|")) { // Split it up, so we know the xref name // and the root layer name int sepIdx = layerName.IndexOf("|"); string xrefName = layerName.Substring(0, sepIdx); string rootName = layerName.Substring(sepIdx + 1); // If the xref is the same as the last loaded, // this saves us some effort // we get the node for our xref, // so we can get its filename XrefGraphNode xgn = xg.GetXrefNode(xrefName); if (xgn != null) { // Create an xrefed database, loading our // drawing into it using (Database xdb = new Database(false, true)) { xdb.ReadDwgFile(xgn.Database.Filename, System.IO.FileShare.Read, true, null); // Start a transaction in our loaded database // to get at the layer name Transaction tr2 = xdb.TransactionManager.StartTransaction(); using (tr2) { // Open the layer table LayerTable lt2 = tr2.GetObject(xdb.LayerTableId, OpenMode.ForRead) as LayerTable; // Add our layer (which we get via its // unmangled name) to the list to clone if (lt2.Has(rootName)) { LayerTableRecord ltr2 = tr2.GetObject(lt2[rootName], OpenMode.ForRead) as LayerTableRecord; // Reset the layer color layerTableRec.Color = ltr2.Color; LinetypeTableRecord lineTypeRec2 = tr2.GetObject(ltr2.LinetypeObjectId, OpenMode.ForRead) as LinetypeTableRecord; String lineTypeRecName = String.Format("{0}|{1}", xrefName, lineTypeRec2.Name); // Reset the line type if(lineTypeTable.Has(lineTypeRecName)) { layerTableRec.LinetypeObjectId = lineTypeTable[lineTypeRecName]; } } tr2.Commit(); } } } } else { ed.WriteMessage("\nNot a dependent layer. Layers from an Xref drawing are dependent"); } } tr.Commit(); } }
In a drawing that has VISRETAIN set to 1, if the dependent layer is assigned a different line type, the one that was imported from the Xref should still be available in the Line table. So, to reset the linetype of a dependent layer, you can find its name from the xref database and use it to reassign it to the layer.
Regards,
Balaji
Also just wanted to add to my previous reply.
In case the linetype is new in the xref database and is not already available in the host database, you can clone it using WblockCloneObjects to make it available locally and then assign it to the layer. This is similar to what a reload of xref would do when VISRETAIN is 0.
Regards,
Balaji
Hi Balaji,
Thank you for your example, you understood it correctly, however problem is when linetype is new in xref as you described in your second message. The approach with WblockCloneObjects I tried already some time ago and it did not work for me. It created true local linetype in host drawing for example HIDDEN, but I could not find out way how to create xref dependant linetype XREF|HIDDEN
Regards,
Richard
Hi Balaji,
thank you very much for your example. But unfurtunately this is exactly what is not working for me.
There is no changing after the: layerTableRec.LinetypeObjectId = lineTypeTable[lineTypeRecName];
Regards
Holger
Hi Richard / Holger,
I do not think it will be possible to get the dependent linetype to be created from the changed Xref drawing without having to reload the xref.
The API to set a linetype dependent is a getter.
But even with VISRETAIN set to 1 in the host drawing, if you reload the drawing, AutoCAD should still add the linetype from the xref drawing to the linetype table. Although in this case, your local changes to the layer would not change.
Since the linetype is available in the linetype table, it should be possible to assign it to the layer through code.
But, I havent got this working yet and have contacted our engineering team.
I will keep you updated.
Thanks
Regards,
Balaji
Hi Jeff,
Yes, your reason sounds logical.
But I would imagine a continuous linetype in that case 🙂
I will keep you updated based on what i hear.
Regards,
Balaji
Hi Holger / Richard / Jeff,
Here is the feedback that i received from my colleague in engineering team.
<<<
The reason the linetype doesn't get assigned is because the linetype belongs to the xref database.
If you iterate through the linetype table of the host drawing, you will encounter linetype table records that belong to the xref database
(i.e. ->database() on the linetype table record will return the xref database).
you can’t set such linetype back to the layer from the API, because all API functions check whether the incoming object id
belongs to the same database than the object itself.
>>>
Regards,
Balaji