CADxp: Modifier attribut d'un bloc importé - CADxp

Aller au contenu

Page 1 sur 1
  • Vous ne pouvez pas commencer un sujet
  • Vous ne pouvez pas répondre à ce sujet

Modifier attribut d'un bloc importé

#1 L'utilisateur est hors-ligne   Goud 

  • Member
  • PipPip
  • Groupe : Membres
  • Messages : 13
  • Inscrit(e) : 20-novembre 18

Posté 01 mai 2019 - 12:38

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.
0

#2 L'utilisateur est hors-ligne   (gile) 

  • ceinture rouge et blanche 8em dan
  • Groupe : Moderateurs
  • Messages : 11181
  • Inscrit(e) : 02-septembre 05

Posté 01 mai 2019 - 14:59

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 -
Développements sur mesure pour AutoCAD
Image IPB
0

#3 L'utilisateur est hors-ligne   Goud 

  • Member
  • PipPip
  • Groupe : Membres
  • Messages : 13
  • Inscrit(e) : 20-novembre 18

Posté 01 mai 2019 - 15:50

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.
0

#4 L'utilisateur est hors-ligne   (gile) 

  • ceinture rouge et blanche 8em dan
  • Groupe : Moderateurs
  • Messages : 11181
  • Inscrit(e) : 02-septembre 05

Posté 01 mai 2019 - 16:53

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 -
Développements sur mesure pour AutoCAD
Image IPB
0

#5 L'utilisateur est hors-ligne   Goud 

  • Member
  • PipPip
  • Groupe : Membres
  • Messages : 13
  • Inscrit(e) : 20-novembre 18

Posté 12 mai 2019 - 16:22

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.
0

Partager ce sujet :


Page 1 sur 1
  • Vous ne pouvez pas commencer un sujet
  • Vous ne pouvez pas répondre à ce sujet

1 utilisateur(s) en train de lire ce sujet
0 membre(s), 1 invité(s), 0 utilisateur(s) anonyme(s)