Aller au contenu

PDF, DWF, DGN, RasterImage


PhilOctet

Messages recommandés

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

Lien vers le commentaire
Partager sur d’autres sites

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

Lien vers le commentaire
Partager sur d’autres sites

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,

Lien vers le commentaire
Partager sur d’autres sites

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

Lien vers le commentaire
Partager sur d’autres sites

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.

Lien vers le commentaire
Partager sur d’autres sites

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 ?

 

 

 

Lien vers le commentaire
Partager sur d’autres sites

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

Lien vers le commentaire
Partager sur d’autres sites

  • 2 semaines après...

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

Lien vers le commentaire
Partager sur d’autres sites

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

Lien vers le commentaire
Partager sur d’autres sites

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

Lien vers le commentaire
Partager sur d’autres sites

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 compte

Se connecter

Vous avez déjà un compte ? Connectez-vous ici.

Connectez-vous maintenant
×
×
  • Créer...

Information importante

Nous avons placé des cookies sur votre appareil pour aider à améliorer ce site. Vous pouvez choisir d’ajuster vos paramètres de cookie, sinon nous supposerons que vous êtes d’accord pour continuer. Politique de confidentialité