Aller au contenu

Messages recommandés

Posté(e)

Bonjour à tous,

 

J'aimerai modifier l'attribut d'un bloc précédemment importé d'un dwg extérieur.

 

J'importe mon bloc :

 

 

public void ajouterblocs()
       {
           // Get the current document and database
           Document acDoc = Application.DocumentManager.MdiActiveDocument;
           Database acCurDb = acDoc.Database;
           Editor ed = acDoc.Editor;

           using (acDoc.LockDocument())
           // Create a transaction for the current drawing
           using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
           {
               BlockTable blkTbl = (BlockTable)acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead);

               if (!blkTbl.Has("COT-altimétrie"))
               {
                   string blockQualifiedFileName = "C:/Users/antoi/Documents/GitHub/GenDet/GenDet/GenDet/blocs/cotealtimetrie.dwg";
                   Database tmpDb = new Database(false, true);
                   tmpDb.ReadDwgFile(blockQualifiedFileName, System.IO.FileShare.ReadWrite, true, "");
                   IdMapping iMap = new IdMapping();
                   ObjectIdCollection ids = new ObjectIdCollection();

                   using (Transaction tr = tmpDb.TransactionManager.StartTransaction())
                   {
                       BlockTable bt = (BlockTable)tr.GetObject(tmpDb.BlockTableId, OpenMode.ForRead);
                       ids.Add(bt["COT-altimétrie"]);
                       ids.Add(bt["COT-altimétrie-inf"]);
                       tr.Commit();
                   }
                   acCurDb.WblockCloneObjects(ids, acCurDb.BlockTableId, iMap, DuplicateRecordCloning.Ignore, false);
               }
               acTrans.Commit();
           }
       }

 

 

Ensuite, j'insère mon bloc dans le Model Space (cela marche) et j'essaie de modifier son attribut mais le "AttributeCollection" est vide :

 

private void cotealti(Document acDoc, Database acCurDb, BlockTable blkTbl, BlockTableRecord btr, Transaction acTrans, double x, double y, double altimetrie, int inf)
       {
           BlockReference bloccotealti;
           if (inf == 1)
               bloccotealti = new BlockReference(new Point3d(x, y, 0), blkTbl["COT-altimétrie-inf"]);
           else
               bloccotealti = new BlockReference(new Point3d(x, y, 0), blkTbl["COT-altimétrie"]);

           using (bloccotealti)
           {
               bloccotealti.TransformBy(Matrix3d.Scaling(500, new Point3d(x, y, 0)));
               
               btr.AppendEntity(bloccotealti);
               acTrans.AddNewlyCreatedDBObject(bloccotealti, true);

               if (inf == 1)
                   acDoc.SendStringToExecute("_.attsync Nom COT-altimétrie-inf" + "\n", true, false, true);
               else
                   acDoc.SendStringToExecute("_.attsync Nom COT-altimétrie" + "\n", true, false, true);

               ObjectId arId = bloccotealti.AttributeCollection[0];
               DBObject objetatt = acTrans.GetObject(arId, OpenMode.ForRead);
               AttributeReference ar = objetatt as AttributeReference;
               ar.UpgradeOpen();
               ar.TextString = altimetrie.ToString();
               ar.DowngradeOpen();
           }
}

 

 

Je n'ai pas copié tout le code car il est très long et sans rapport avec le problème je pense. N'hésitez pas à me demander ce que j'ai oublié de préciser pour que vous puissiez, je l'espère, m'aider.

 

Merci

 

 

Edit :

Lorsque je mets en commentaires la partie de modification de l'attribut, le bloc est bien inséré et je peux modifier son attribut manuellement.

Posté(e)

Salut,

 

En .NET (comme en AutoLISP avec entmake), il revient au programme de créer explicitement les références d'attribut liée à la référence de bloc insérée.

Tu peux voir ce sujet de la documentation du développeur.

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Posté(e)

Salut Gille,

 

Oui je me suis justement inspiré de ce sujet pour la partie de modification de l'attribut.

 

Mon programme est appelé depuis un bouton créé sur une palette (WPF) insérée. Si j'essaie d'insérer le bloc + modifier son attribut à partir du même bouton de la palette, cela donne le problème évoqué dans mon premier message.

En revanche, si j'insère le bloc depuis un bouton puis j'essaie de modifier son attribut à partir d'un 2ème bouton, cela fonctionne correctement.

 

Je me suis dis qu'il était possible de faire les deux sans passer par un second bouton.

Posté(e)

Le problème avec ton code, c'est que tu ajoutes les références d'attribut avec la commande ATTSYNC que tu lances avec SendStringToExecute qui est asynchrone (la commande n'est exécutée qu'a la fin de la méthode).

 

Tu peux ajouter explicitement les attributs comme dans le code de la documentation.

 

        private void CoteAlti(Database db, BlockTable bt, BlockTableRecord owner, Transaction tr, double x, double y, double alt, int inf)
       {
           BlockReference blocCoteAlti;
           if (inf == 1)
               blocCoteAlti = new BlockReference(new Point3d(x, y, 0), bt["COT-altimétrie-inf"]);
           else
               blocCoteAlti = new BlockReference(new Point3d(x, y, 0), bt["COT-altimétrie"]);

           using (blocCoteAlti)
           {
               blocCoteAlti.TransformBy(Matrix3d.Scaling(500, new Point3d(x, y, 0)));

               owner.AppendEntity(blocCoteAlti);
              tr.AddNewlyCreatedDBObject(blocCoteAlti, true);

               // ajout des références d'attribut
               var btr = (BlockTableRecord)tr.GetObject(blocCoteAlti.BlockTableRecord, OpenMode.ForRead);
               bool first = true;
               foreach (ObjectId id in btr)
               {
                   if (id.ObjectClass.DxfName == "ATTDEF")
                   {
                       var attDef = (AttributeDefinition)tr.GetObject(id, OpenMode.ForRead);
                       if (!attDef.Constant)
                       {
                           var attRef = new AttributeReference();
                           attRef.SetAttributeFromBlock(attDef, blocCoteAlti.BlockTransform);
                           if (first)
                               attRef.TextString = alt.ToString();
                           first = false;
                           owner.AppendEntity(attRef);
                           tr.AddNewlyCreatedDBObject(attRef, true);
                       }
                   }
               }
           }
       }

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

  • 2 semaines après...
Posté(e)

Bonjour gile,

 

Merci pour ta réponse !

J'avais en revanche une erreur du type ":eIllegalEntityType".

J'ai juste du remplacer "owner.AppendEntity(attRef);" par "bloccotealti.AttributeCollection.AppendAttribute(attRef);" pour que cela fonctionne.

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é