(gile) Posté(e) le 24 janvier 2010 Posté(e) le 24 janvier 2010 J'ai pas mal étudier ton code. Je ne connaissais pas cette façon d'extraire les Xrefs. Je n'ai pas encore tous compris mais je vais forcer quelques neurones défaillantes. Vois ce sujet. Tu dis que cela fonctionne avec les dwf. Je te rassure en te disant que cela fonctionne avec tous les dictionaires de type Underlay. Chez moi ça ne fonctionne pas avec les PDF : dans un dessin ne contenant qu'un PDF, la routine fait planter irrémédiablement. Comment puis-je te joindre un e-transmit ? string.Format("{0}@{1}", "chanteau.gilles", "orange.fr"); Pourquoi reçois-je 7 messages de notification de réponse sur ma messagerie ? Aucune idée. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
(gile) Posté(e) le 25 janvier 2010 Posté(e) le 25 janvier 2010 Par curiosité, j'ai essayé en LISP d'attribuer un chemin relatif à des objets sous-jacents et j'ai exactement le même résultat : pas de problème avec les DWF et plantage systématique avec un PDF. Le problème semble donc bien venir des objets sous-jacents PDF et pas de la routine. Le LISP utilisé pour les tests(defun c:test (/ obj) (if (and (setq obj (car (entsel "\Sélectionnez un objet sous-jacent: "))) (setq obj (vlax-ename->vla-object obj)) (member (vla-get-ObjectName obj) '("AcDbDwfReference" "AcDbDgnReference" "AcDbPdfReference") ) ) (vla-put-File obj (GetRelativePath (getvar 'dwgprefix) (vla-get-File obj))) (princ "\nEntité non valide") ) (princ) ) (defun GetRelativePath (dir file / a b) (setq dir (vl-string-right-trim "\\" dir)) (if (/= (strcase (substr dir 1 1)) (strcase (substr file 1 1))) file (progn (while (= (strcase (substr dir 1 (setq a (vl-string-position 92 dir)))) (strcase (substr file 1 (setq b (vl-string-position 92 file)))) ) (setq dir (if a (substr dir (+ 2 a)) "" ) file (substr file (+ 2 b)) ) ) (if (= dir "") (strcat ".\\" file) (progn (while (setq a (vl-string-position 92 dir)) (setq file (strcat "..\\" file) dir (substr dir (+ 2 a)) ) ) (strcat "..\\" file) ) ) ) ) ) Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
PhilOctet Posté(e) le 27 janvier 2010 Auteur Posté(e) le 27 janvier 2010 Bonjour, C'est vraiment bizarre, en AutoLISP comme en VB.Net, lorsque je traite que les PDFs, cela ne plante rien.Et je pense pas que cela soit dû à la version d'AutoCAD. J'ai essayé avec MAP, la 2010 et la 2011. En étudiant ton code en C#, ci-dessus, je me suis aperçu qu'il ne sauvegardait pas les chemins relatifs pour les DWGs.Considérant la 1ere phrase, est-ce que chez toi, cela fait la même chose ? A bientôt,
(gile) Posté(e) le 27 janvier 2010 Posté(e) le 27 janvier 2010 C'est vraiment bizarre, en AutoLISP comme en VB.Net, lorsque je traite que les PDFs, cela ne plante rien.Et je pense pas que cela soit dû à la version d'AutoCAD. J'ai essayé avec MAP, la 2010 et la 2011. Tout ce qu'on semble pouvoir dire, c'est que le comportement est le même avec .NET et LISP et que ça plante différemment suivant le poste indépendamment de la version d'AutoCAD (testé sur 2007 et 2010). En étudiant ton code en C#, ci-dessus, je me suis aperçu qu'il ne sauvegardait pas les chemins relatifs pour les DWGs. Si, cette ligne remplace le chemin complet par le chemin relatif :btr.PathName = GetRelativePath(folder, btr.PathName);Il faut recharger les xrefs pour voir le changement. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
PhilOctet Posté(e) le 27 janvier 2010 Auteur Posté(e) le 27 janvier 2010 Bonsoir, La finalité de cet outil est que je voudrai qu'il s'exécute lors de la fermeture du dessin traité. Je sais qu'il existe des évênements .net qui le permettent. Avez-vous un p'tit exemple à m'offrir. Donc Objectif : je lance les traitements ci-dessus lorsque l'utilisateur sort de son dessin en sauvegardant ou lors de toutes sauvegardes. Encore une fois merci de votre aide.
(gile) Posté(e) le 27 janvier 2010 Posté(e) le 27 janvier 2010 Re, Je t'avais donné un exemple d'évènements à la fermeture des documents ici. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
PhilOctet Posté(e) le 27 janvier 2010 Auteur Posté(e) le 27 janvier 2010 Oui, je l'ai bien eu et le système me dit bien au revoir mais lorsque je ferme mon dessin après avoir lancé les traitements ci-dessus. Aucun problème il se ferme bien.Mais lorsque je le reouvre, les XRefs sont toujours en absolu. Donc la routine n'a rien sauvegardée. Je pense que je dois accompagner le "Application.ShowAlertDialog("Au revoir ...")" par la Sub Test.' Réaction à l'évènement "BeginDocumentClose" Private Sub docBeginDocClose(ByVal sender As Object, ByVal e As DocumentBeginCloseEventArgs) Call Test() Application.ShowAlertDialog("Au revoir ...") End Sub Où ou Comment est déclenché la sauvegarde ? C'est AutoCAD qui s'en charge ?
(gile) Posté(e) le 27 janvier 2010 Posté(e) le 27 janvier 2010 L'évènement DocumentBeginClose intervient après la sauvegarde du document, il faut donc- soit ajouter un Database.SaveAs() dans docBeginDocClose ou dans Test- soit utiliser un évènement Database.BeginSave mais dans ce cas la routine serait exécutée à chaque sauvegarde. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
(gile) Posté(e) le 6 février 2010 Posté(e) le 6 février 2010 Salut, Je ne garantis rien mais il me semble avoir trouvé un moyen pour éviter le plantage en renommant les chemins en relatif.Il faut décharger les objets sous-jacents, les renommer et les recharger.J'ai essayé avec un fichier contenant xrefs, dwf, pdf et images raster et ça fonctionne. using System; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Runtime; using acadApp = Autodesk.AutoCAD.ApplicationServices.Application; namespace RelativePath { public class Class1 { [CommandMethod("Test")] public void Test() { Document doc = acadApp.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; string folder = (string)acadApp.GetSystemVariable("DWGPREFIX"); folder = folder.Trim(new char[] { '\\' }); using (Transaction tr = db.TransactionManager.StartTransaction()) { XrefGraph xrg = db.GetHostDwgXrefGraph(true); ObjectIdCollection xrefs = new ObjectIdCollection(); for (int i = 1; i { XrefGraphNode xrgn = xrg.GetXrefNode(i); if ((!xrgn.IsNested) && (xrgn.XrefStatus != XrefStatus.FileNotFound)) { try { xrefs.Add(xrgn.BlockTableRecordId); BlockTableRecord btr = (BlockTableRecord)tr.GetObject(xrgn.BlockTableRecordId, OpenMode.ForWrite); btr.PathName = GetRelativePath(folder, btr.PathName); } catch (System.Exception ex) { ed.WriteMessage("\nErreur: " + ex.Message); } } } if (xrefs.Count > 0) db.ReloadXrefs(xrefs); DBDictionary NOD = (DBDictionary)tr.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForRead); // Traitement des objets sous-jacents string[] dicts = new string[3] { "ACAD_DWFDEFINITIONS", "ACAD_DGNDEFINITIONS", "ACAD_PDFDEFINITIONS" }; foreach (string str in dicts) { if (NOD.Contains(str)) { DBDictionary dict = (DBDictionary)tr.GetObject(NOD.GetAt(str), OpenMode.ForRead); foreach (DBDictionaryEntry entry in dict) { try { UnderlayDefinition uDef = (UnderlayDefinition)tr.GetObject(entry.Value, OpenMode.ForWrite); uDef.Unload(); uDef.SourceFileName = GetRelativePath(folder, uDef.SourceFileName); uDef.Load(string.Empty); } catch (System.Exception ex) { ed.WriteMessage("\nErreur: " + ex.Message); } } } } // Traitement des images if (NOD.Contains("ACAD_IMAGE_DICT")) { DBDictionary dict = (DBDictionary)tr.GetObject(NOD.GetAt("ACAD_IMAGE_DICT"), OpenMode.ForRead); foreach (DBDictionaryEntry entry in dict) { try { RasterImageDef img = (RasterImageDef)tr.GetObject(entry.Value, OpenMode.ForWrite); img.Unload(true); img.SourceFileName = GetRelativePath(folder, img.SourceFileName); img.Load(); } catch (System.Exception ex) { ed.WriteMessage("\nErreur: " + ex.Message); } } } tr.Commit(); } } // Retourne le chemin relatif de fichier par rapport au dossier private string GetRelativePath(string folder, string filename) { if (folder.StartsWith(filename.Substring(1, 2)) || filename.StartsWith(".")) return filename; char[] chr = new char[1] { '\\' }; string[] foldArray = folder.Trim(chr).Split(chr); string[] fileArray = filename.Split(chr); int foldLength = foldArray.Length; int fileLength = fileArray.Length; int l = (foldLength int i = 0; for (; i { if (!foldArray[i].Equals(fileArray[i], StringComparison.CurrentCultureIgnoreCase)) break; } string result = fileArray[i]; for (int j = i + 1; j { result += "\\" + fileArray[j]; } if (i == foldArray.Length) return ".\\" + result; for (; i { result = "..\\" + result; } return result; } } } Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
PhilOctet Posté(e) le 8 février 2010 Auteur Posté(e) le 8 février 2010 Bonjour, Cela ne change rien. J'ai effacé (avec uDef.erase()) le PDF puis réinséré ce même PDF avec toutes les caractèristiques de l'ancien PDF. Cela plante quand même AutoCAD. Par contre, lorsque je traite mon fichier dessin non ouvert avec un dtb.ReadDwgFile(filename, System.IO.FileShare.ReadWrite, True, String.Empty), cela ne plante pas AutoCAD et lorsque j'ouvre le dessin maitre, j'ai toutes les XRefs, y compris les PDFs, qui sont bien en adressage relatif. Du coup, je suis perplexe. cela fonctionne avec AutoCAD losrque le dessin est fermé par contre cela ne fontionne plus lorsque ce même dessin est en cours d'utilisation. A suivre, merci
(gile) Posté(e) le 8 février 2010 Posté(e) le 8 février 2010 La routine ci-dessus fonctionne chez moi sur un dessin ouvert (le dessin courant). Je ne sais pas comment ton programme fonctionne, mais ReadDwg ne fonctionne que sur des dessins fermés. Sur des dessins ouverts dans la même session autre que le dessin courant, il faut verrouiller le document (LockDocument) pour pouvoir le modifier. Sur des dessins ouverts dans une autre session, je crois bien qu'il n'est pas possible d'intervenir. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
Messages recommandés
Créer un compte ou se connecter pour commenter
Vous devez être membre afin de pouvoir déposer un commentaire
Créer un compte
Créez un compte sur notre communauté. C’est facile !
Créer un nouveau compteSe connecter
Vous avez déjà un compte ? Connectez-vous ici.
Connectez-vous maintenant