Aller au contenu

Messages recommandés

Posté(e)

Bonjour,

 

Problème:

J'ai de la cotation dans un bloc dynamique et des hachures associative. Lorsque je modifie le paramètre par programme, le bloc est mis à jour mais les cotations et le hachurage ne se mettent pas à jour. Que puis-je faire pour résoudre cela?

 

La Solution (semblerait-il ....)

Lorsque le paramètre est modifié, AutoCAD crée un nouveau bloc anonyme. Pour s'assurer que la dimension et le hachurage soit également mise à jour pour refléter la modification du paramètre, ce bloc anonyme doit être ouvert pour écriture et marqué comme "modified". Cela garantira qu'AutoCAD met à jour la dimension.

 

J'ai besoin de la méthode qui permet de faire cette mise à jour, seulement le code associé à cette solution est en "C" et je ne sais pas la ré-écrire en VB.net. (lien où j'ai trouvé la solution à mon problème : //adndevblog.typepad.com/autocad/2012/09/updating-dimensions-associated-with-a-dynamic-block.html

 

Je code actuellement sous Visual Studio Express 2017 en VB.net avec Autocad Mechanical 2016 et je n’utilise pas d’inter-op, tout mon code est en managé.

 

Est-ce que quelqu'un peut m'aider ? J'ai écrit un bout de méthode mais ce n'est pas concluant ... je dois me tromper quelque part ....

 

 ''' <summary>
   ''' JR le 26.07.18 : Met à jour la partie graphique (cotation / hachurage) d'un bloc dynamique lorsque le paramètre est modifié,
   ''' AutoCAD crée un nouveau bloc anonyme et pour s'assurer que la dimension (ou hachuure) soit également mise à jour pour refléter la modification du paramètre,
   ''' ce bloc anonyme doit être ouvert pour "write" et marqué comme "modified". Cela garantira qu'AutoCAD met à jour la partie graphique des cotations et hachures.
   ''' </summary>
   ''' <param name="oNomBloc">Le nom du bloc à mettre à jour</param>

   Public Sub MAJAnonymousBloc(oNomBloc As String,
                                   Optional Report As Boolean = False)     'Met à jour la visibilité des blocs dynamiques
       Try
           Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
           Dim db As Database = doc.Database
           Dim ed As Editor = doc.Editor
           Dim bref As BlockReference
           Dim props As DynamicBlockReferencePropertyCollection
           Dim btrIds As ObjectIdCollection
           Dim btrAnonIds As ObjectIdCollection

           Dim MAJFaite As Boolean = False

           Dim Inspect As Boolean = False


           Using doclock As DocumentLock = doc.LockDocument
               Using tr As Transaction = db.TransactionManager.StartTransaction
                   Dim bt As BlockTable
                   bt = CType(tr.GetObject(db.BlockTableId, OpenMode.ForWrite), BlockTable)
                   Dim btr As BlockTableRecord
                   For Each id As ObjectId In bt
                       btr = CType(tr.GetObject(id, OpenMode.ForWrite), BlockTableRecord)

                       btrIds = btr.GetBlockReferenceIds(True, True)
                       btrAnonIds = btr.GetAnonymousBlockIds
                       For Each anonObjId As ObjectId In btrAnonIds
                           Dim btrAnon As BlockTableRecord = DirectCast(anonObjId.GetObject(OpenMode.ForRead), BlockTableRecord)
                           Dim ObjidColl As ObjectIdCollection = btrAnon.GetBlockReferenceIds(True, True)
                           For Each idAnon As ObjectId In ObjidColl
                               btrIds.Add(idAnon)
                           Next
                       Next
                       For Each idMaster As ObjectId In btrIds
                           bref = Nothing
                           bref = TryCast(tr.GetObject(idMaster, OpenMode.ForWrite), BlockReference)
                           If bref IsNot Nothing Then
                               If bref.IsDynamicBlock AndAlso mod_Principal.GETNomReelBlock(tr, bref) = oNomBloc Then
                                   If Inspect Then mod_FichierError.EcritureRapport("Bloc trouvé=" & oNomBloc)
                                   props = bref.DynamicBlockReferencePropertyCollection

                                   For Each prop As DynamicBlockReferenceProperty In props
                                       bref.RecordGraphicsModified(True) 'La commande importante ce trouve ici pour demander la mise à jour des graphiques
                                   Next
                               End If
                           End If
                       Next
                       If MAJFaite Then Exit For
                   Next
                   tr.Commit()
               End Using
           End Using
           If Not MAJFaite AndAlso Report Then
               Throw New System.Exception("Erreur MAJAnonymousBloc: Bloc non trouvée.")
           End If
       Catch ex As System.Exception
           mod_Exception.Traiter_Exception(ex, "oNomBloc: " & oNomBloc)
       End Try
   End Sub

 

Cordialement.

Posté(e)

Salut,

 

Est-ce que ton bloc dynamique fonctionne correctement quand tu le modifies "à la main" (sans programmation) ?

 

Personnellement, j'ai souvent modifié les propriétés dynamiques de blocs avec hachures et/ou côtes par programmation sans avoir besoin de faire de mise à jour spécifique (ni même appeler RecordGraphicsModified().

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

Posté(e)
Salut, Est-ce que ton bloc dynamique fonctionne correctement quand tu le modifies "à la main" (sans programmation) ? Personnellement, j'ai souvent modifié les propriétés dynamiques de blocs avec hachures et/ou côtes par programmation sans avoir besoin de faire de mise à jour spécifique (ni même appeler RecordGraphicsModified().

 

Salut, Oui tout à fait, quand je modifie les bloc à la main tout fonctionne très bien.

*Voir pièce jointe pour 2 bloc dynamique qui posent problème. Sur ces bloc, les hachures de "GaineVdd" ainsi que les cotes de "CabineVdd" ne se mettent pas à jour.

 

Pour comprendre un peu mieux ce qui m'arrive : Je travail actuellement sur un modèle de plan qui est bien plus sophistiqué que la version précédente, et ce qui est nouveau c'est que j'utilise de l'imbrication de bloc dynamique sur 2 niveaux pour gérer une bibliothèque de porte (MéthodeMajVisibiliteNomBloc), et pour piloter la porte j'utilise une table de consultation. Tout fonctionne bien, sauf cette mise à jour "graphique".

 

D'ailleurs je m'en suis vu avec cette consultation, car pour passer tout les paramètres je suis obligé de choisir 2 ou 3 fois le même choix de consultation pour obtenir le bon résultat quand je manipule le bloc à la main, du coup je fais la même chose dans mon programme en rappelant 2 ou 3 fois la méthode pour être sure que le bloc prenne bien tout les paramètres.

 

Je m'oriente sur une autre solution, pour mon programme je vais plutôt passer par un fichier xml ou csv pour externaliser les données de la table de consultation et refaire des tests en passant les valeurs au différents paramètres de mon bloc, c'est ce que j'ai toujours utilisé jusqu'à maintenant et je n’ai jamais eu de problème ... ce système de consultation me semble, excusez moi du terme, "Foireuse" !

Effectivement jusque là je n'avais eu besoin de faire de mise à jour spécifique, mais il semblerait que le problème ou phénomène intervient pour X raisons .... le nombre et la complexité des bloc dynamiques que contient le plan ... la manière dont on programme ... l’utilisation de certains paramètre comme la consultation que la Database gère mal ...

 

Bref, comme palliatif je n'ai trouvé que cette solution de méthode de "Forçage" de mise à jour graphique.

 

Dans le comportement d'Autocad, quand j'ouvre le plan qui a était utilisé par mon programme, tout est ok sauf la partie graphique. Regen ne fait rien, il faut simplement ouvrir et fermer le bloc dynamique en question pour que la partie graphique ce mette à jour ... de prime abord j'avoue avoir classé ce comportement dans le domaine du mystique sauf que j'ai trouvé sur AdnDevBlog exactement mon sujet mais le bout de code reste à faire.

 

Voilà où j'en suis, je vais reprendre les tests aujourd'hui si j'ai le temps.

C'est grave Docteur ? :blink:

*PS : je ne peux pas Uploader de fichier .... sécurité réseau de m... du coup pour le fichier DWG est sur mon Drive : //autode.sk/2uT3U3R

Posté(e)

Bonjour,

J'ai refait pas mal de test, et mon problème est insolvable pour le moment ...

Autocad ce comporte de la manière suivante :

- Le programme fait ce qu'il a à faire pour passer les paramètres et les visibilités au plan --> la c'est OK

-Les cotes et hachures ne se mettent pas à jour ...

- J'ouvre et je ferme les bloc dynamique à la main, un Regen, et là tout est ok.

C'est sur ce dernier point qu'il faut que je reproduise par du code cette méthode de mise à jour.

(Gile) peux-tu m'aider car là je désespère ...Help !!!!

Posté(e)

Je vois mal comment t'aider sans avoir le bloc ni voir le code...

Mais par principe, les blocs dynamiques imbriqués dans d'autre blocs, ça peut être problématique à gérer par programmation à moins de créer la définition du bloc propriétaire par programmation.

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

Posté(e)

Je vois mal comment t'aider sans avoir le bloc ni voir le code...

Mais par principe, les blocs dynamiques imbriqués dans d'autre blocs, ça peut être problématique à gérer par programmation à moins de créer la définition du bloc propriétaire par programmation.

 

Bonjour,

 

J'ai trouvé !!! mais par contre mon programme est devenu très long, mais ça s'explique ...

J'ai ajouté dans mon code à chaque fin de transaction sur mes fonctions qui contrôlent mes bloc paramétrique, 2 chose :

 Next
                   tr.Commit()
                   tr.Dispose()
                   doc.Editor.Regen()

En ajoutant "Dispose et Regen" plus de problème ... sauf le temps de traitement qui a quasi doublé.

Comme je fais énormément d'appel (+ de 100) sur ces fonctions, il va falloir trouver autre chose.

 

J'ai bricoler une méthode pour faire le post traitement du rafraichissement du plan que j'implémenterais à des endroits stratégique :

 

Friend Shared Sub Refresh_Plan()
       Try
           mod_Principal.UpdateField()                                                                           
           Autodesk.AutoCAD.ApplicationServices.Application.UpdateScreen()
           Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor.UpdateScreen()
           Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor.Regen()
       Catch ex As Exception
           mod_Exception.Traiter_Exception(ex)
       End Try
   End Sub

 

Public Sub UpdateField()
       Try
           Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
           Dim db As Database = doc.Database
           Using doc.LockDocument
               Using tr As Transaction = db.TransactionManager.StartTransaction()
                   Try
                       Dim bt As BlockTable = DirectCast(tr.GetObject(db.BlockTableId, OpenMode.ForRead), BlockTable)
                       For Each btrId As ObjectId In bt
                           Dim btr As BlockTableRecord = DirectCast(tr.GetObject(btrId, OpenMode.ForRead), BlockTableRecord)
                           For Each objID As ObjectId In btr
                               Dim objEnt As Entity = DirectCast(tr.GetObject(objID, OpenMode.ForRead), Entity)
                               If TypeOf objEnt Is MText Then
                                   Dim objMtext As MText = DirectCast(tr.GetObject(objID, OpenMode.ForRead), MText)
                                   If objMtext.HasFields Then
                                       Dim fieldID As ObjectId = objMtext.GetField
                                       Dim field As Field = DirectCast(tr.GetObject(fieldID, OpenMode.ForWrite), Field)
                                       field.Evaluate()
                                       Dim cEval As String = field.Value.ToString
                                   End If
                               ElseIf TypeOf objEnt Is Dimension Then
                                   Dim objDim As Dimension = DirectCast(tr.GetObject(objID, OpenMode.ForWrite), Dimension)
                                   If objDim.HasFields Then
                                       Dim fieldID As ObjectId = objDim.GetField
                                       Dim field As Field = DirectCast(tr.GetObject(fieldID, OpenMode.ForWrite), Field)
                                       field.Evaluate()
                                       Dim cEval As String = field.Value.ToString
                                   End If
                                  
                               End If
                           Next
                       Next
                       tr.Commit()
                       tr.Dispose()
                   Catch ex As System.Exception
                       tr.Abort()
                       Throw New System.Exception(ex.Message)
                   End Try
               End Using

           End Using
       Catch ex As System.Exception
           mod_Exception.Traiter_Exception(ex)
       End Try
   End Sub

 

Pour ce qui est des bloc dynamique récalcitrant, j'ai établi une procédure pour les "initialisés", je met des guillemets car je ne comprend pas pourquoi il a fallu que j'en arrive là pour que certain bloc ce comporte normalement dans le ModelSpace. Je passe systématiquement par l'éditeur de bloc, je le test, je ferme et j'enregistre, je le ré-initialise, et je passe au moins un paramètre puis Regen, purge et enregistrement du model de plan. Avec ça, les cotes et hachures ont l'aire de bien ce comporter.

 

Pour info les modèles de plan sur lesquels je travail font 10/15 Mo.

 

Voilà Gile pour mon retour d’expérience, j'espère que ça aidera d'autres internautes et si tu as des éléments intéressant sur le sujet je suis preneur. Cordialement.

Posté(e)

Tu n'as pas besoin d'appeler Dispose() sur une transaction démarrée avec une instruction Using, ce sera fait automatiquement lors du End Using.

Tu n'as pas besoin d'appeler Abort() en cas d'erreur, ce sera fait automatiquement puisque l'exécution s'arrêtera avant le Commit().

Tu n'as pas besoin de faire un Try/Catch sur tout le contenu de l'instruction Using si celle-ci est déjà à l'intérieur d'un autre Try/Catch.

 

    Public Sub UpdateField()
       Try
           Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
           Dim db As Database = doc.Database
           Using doc.LockDocument
               Using tr As Transaction = db.TransactionManager.StartTransaction()
                   [...]
                   tr.Commit()
               End Using
           End Using
       Catch ex As System.Exception
           mod_Exception.Traiter_Exception(ex)
       End Try
   End Sub

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

  • 1 mois après...
Posté(e)

Merci Gile pour ces précisions, je vais refaire des test en retirant tout ça pour voire.

Je ferais un retour là-dessus dès que possible.

 

Au final je n'ai pas trouvé comment palier à ce problème d'anonymous block, enfin pas exactement comme je l'espérer, c'est à dire, avec du code. Le moyen que j'ai trouvé est basic, la manip consiste à purger le plan et copier/coller les objets dans un fond de plan à km 0 (Am-iso.dwt par exemple) et ça a corrigé mon problème.

 

Si un jour quelqu'un peu partager son code sur ce sujet ....

 

Merci quand même Gile.

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é