CADxp: Anonymous block - CADxp

Aller au contenu

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

Anonymous block Mise à jour des dimensions associées à un bloc dynamique

#1 L'utilisateur est hors-ligne   juh0026 

  • ceinture orange
  • Groupe : Membres
  • Messages : 22
  • Inscrit(e) : 02-août 07

Posté 26 juillet 2018 - 16:13

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

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

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

Posté 26 juillet 2018 - 19:17

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

#3 L'utilisateur est hors-ligne   juh0026 

  • ceinture orange
  • Groupe : Membres
  • Messages : 22
  • Inscrit(e) : 02-août 07

Posté 27 juillet 2018 - 07:26

Voir le message(gile), le 26 juillet 2018 - 19:17 , dit :

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
0

#4 L'utilisateur est hors-ligne   juh0026 

  • ceinture orange
  • Groupe : Membres
  • Messages : 22
  • Inscrit(e) : 02-août 07

Posté 30 juillet 2018 - 10:56

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

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

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

Posté 30 juillet 2018 - 18:15

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

#6 L'utilisateur est hors-ligne   juh0026 

  • ceinture orange
  • Groupe : Membres
  • Messages : 22
  • Inscrit(e) : 02-août 07

Posté 31 juillet 2018 - 15:17

Voir le message(gile), le 30 juillet 2018 - 18:15 , dit :

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

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

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

Posté 31 juillet 2018 - 15:36

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

#8 L'utilisateur est hors-ligne   juh0026 

  • ceinture orange
  • Groupe : Membres
  • Messages : 22
  • Inscrit(e) : 02-août 07

Posté 31 juillet 2018 - 16:14

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

#9 L'utilisateur est hors-ligne   juh0026 

  • ceinture orange
  • Groupe : Membres
  • Messages : 22
  • Inscrit(e) : 02-août 07

Posté 20 septembre 2018 - 15:06

Voir le messagejuh0026, le 31 juillet 2018 - 16:14 , dit :

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