FreeCAD Logo FreeCAD 1.0
  • Anglais Afrikaans Arabe Biélorusse Catalan Tchèque Allemand Grec Espagnol Espagnol Basque Finnois Philippin Français Galicien Croate Hongrois Indonésien Italien Japonais Kabyle Coréen Lituanien Néerlandais Norvégien classique Polonais Portugais Portugais Roumain Russe Slovaque Slovène Serbe Suédois Turc Ukrainien Valencien Vietnamien Chinois Chinois
  • Fonctions
  • Télécharger
  • Blog
  • Documentation
    Index de la documentation Premiers pas Documentation pour les utilisateurs Manuel de FreeCAD Documentation des ateliers Documentation sur le codage en Python Documentation pour les développeurs Tutoriels Foire aux questions Politique de confidentialité À propos de FreeCAD
  • Contribuer
    Comment aider Sponsor Signaler un bogue Faire une demande de modification (PR) Emplois et financements Guide pour les contributions Manuel pour les développeurs Traductions
  • Communauté
    Code de conduite Forum The FPA GitHub GitLab Codeberg Mastodon Matrix IRC IRC via Webchat Gitter Discord Reddit Twitter Facebook LinkedIn Calendrier
  • ♥ Donate

Donate

$
Informations SEPA
Veuillez configurer votre virement bancaire SEPA pour:
Beneficiary: The FreeCAD project association
IBAN: BE04 0019 2896 4531
BIC/SWIFT: GEBABEBBXXX
Agence bancaire: BNP Paribas Fortis
Adresse: Rue de la Station 64, 1360 Perwez, Belgium

While Stripe doesn't support monthly donations, you can still become a sponsor! Simply make a one-time donation equivalent to 12 months of support, and you'll gain access to the corresponding sponsoring tier. It's an easy and flexible way to contribute.

If you are not sure or not able to commit to a regular donation, but still want to help the project, you can do a one-time donation, of any amount.

Choose freely the amount you wish to donate one time only.

You can support FreeCAD by sponsoring it as an individual or organization through various platforms. Sponsorship provides a steady income for developers, allowing the FPA to plan ahead and enabling greater investment in FreeCAD. To encourage sponsorship, we offer different tiers, and unless you choose to remain anonymous, your name or company logo will be featured on our website accordingly.

from 1 USD / 1 EUR per month. You will not have your name displayed here, but you will have helped the project a lot anyway. Together, normal sponsors maintain the project on its feet as much as the bigger sponsors.

from 25 USD / 25 EUR per month. Your name or company name is displayed on this page.

from 100 USD / 100 EUR per month. Your name or company name is displayed on this page, with a link to your website, and a one-line description text.

from 200 USD / 200 EUR per month. Your name or company name and logo displayed on this page, with a link to your website and a custom description text. Companies that have helped FreeCAD early on also appear under Gold sponsors.

Instead of donating each month, you might find it more comfortable to make a one-time donation that, when divided by twelve, would give you right to enter a sponsoring tier. Don't hesitate to do so!

Choose freely the amount you wish to donate each month.

Please inform your forum name or twitter handle as a notein your transfer, or reach to us, so we can give you proper credits!

Introduction

Les Objets créés par script sont reconstruits à chaque fois qu'un document au format FCStd est ouvert. Pour ce faire, le document conserve une référence au module et à la classe Python qui ont été utilisés pour créer l'objet, ainsi que ses propriétés.

Les attributs de la classe utilisée pour créer l'objet peuvent également être enregistrés, c'est-à-dire "sérialisés". Ceci peut être contrôlé par les méthodes dumps et loads de la classe.

Sauvegarde de tous les attributs

Par défaut, les attributs enregistrés dans une classe d'objets sont ceux du dictionnaire __dict__ de la classe.

# various_states.py
class VariousStates:
    def __init__(self, obj):
        obj.addProperty("App::PropertyLength", "Length")
        obj.addProperty("App::PropertyArea", "Area")
        obj.Length = 15
        obj.Area = 300
        obj.Proxy = self

        Type = dict()
        Type["Version"] = "Custom"
        Type["Release"] = "production"
        self.Type = Type
        self.Type = "Custom"
        self.ver = "0.18"
        self.color = (0, 0, 1)
        self.width = 2.5

    def execute(self, obj):
        pass

Un objet peut être créé à l'aide de cette classe et il peut être enregistré dans my_document.FCstd. Si aucun viewprovider particulier n'est attribué au nouvel objet, sa classe proxy est simplement définie sur une valeur différente de None, dans ce cas, sur 1.

import FreeCAD as App
import various_states

doc = App.newDocument()
doc.FileName = "my_document.FCStd"

obj = doc.addObject("Part::FeaturePython", "Custom")
various_states.VariousStates(obj)

if App.GuiUp:
    obj.ViewObject.Proxy = 1

doc.recompute()
doc.save()

Lorsque nous rouvrons le fichier, nous pouvons inspecter le dictionnaire de la classe de l'objet.

>>> obj = App.ActiveDocument.Custom
>>> print(obj.Proxy)
<various_states.VariousStates object at 0x7f0a899bde10>
>>> print(obj.Proxy.__dict__)
{'Type': {'Version': 'Custom', 'Release': 'production'}, 'ver': '0.18', 'color': [0, 0, 1], 'width': 2.5}

Nous voyons que tous les attributs qui commencent par self dans la classe ont été sauvegardés. Ceux-ci peuvent être de différents types, notamment chaîne de caractères, liste, flottant et dictionnaire. Le tuple original pour self.color a été converti en liste, mais sinon tous les attributs ont été chargés de la même manière.

Sauvegarde d'attributs spécifiques

Nous pouvons définir une classe similaire à la première, qui implémente des attributs spécifiques à sauvegarder.

# various_states.py
class CustomStates:
    def __init__(self, obj):
        obj.addProperty("App::PropertyLength", "Length")
        obj.addProperty("App::PropertyArea", "Area")
        obj.Length = 15
        obj.Area = 300
        obj.Proxy = self

        Type = dict()
        Type["Version"] = "Custom"
        Type["Release"] = "production"
        self.Type = Type
        self.ver = "0.18"
        self.color = (0, 0, 1)
        self.width = 2.5

    def execute(self, obj):
        pass

    def dumps(self):
        return self.color, self.width

    def loads(self, state):
        self.color = state[0]
        self.width = state[1]

La valeur de retour de dumps est l'objet qui sera sérialisé. Il peut s'agir d'une valeur unique ou d'un tuple de valeurs. Lorsque l'objet est restauré, la classe appelle la méthode loads, en passant la variable state avec le contenu sérialisé. Dans ce cas, state est un tuple qui est décomposé dans les variables respectives pour reconstruire l'"état" qui existait à l'origine.

state = (self.color, self.width)
state = ((0, 0, 1), 2.5)

Nous pouvons créer un objet avec cette classe et enregistrer le document, comme dans l'exemple précédent. Lorsque nous rouvrons le fichier, nous pouvons inspecter le dictionnaire de la classe de l'objet.

>>> obj2 = App.ActiveDocument.Custom2
>>> print(obj2.Proxy)
<various_states.CustomStates object at 0x7fb399496630>
>>> print(obj2.Proxy.__dict__)
{'color': [0, 0, 1], 'width': 2.5}

Le tuple original de self.color a été converti en liste, mais les autres informations ont été récupérées sans problème. Au lieu de restaurer tous les attributs comme dans le cas précédent, seuls les attributs que nous avons spécifiés dans dumps et loads ont été restaurés.

Utilisation

Identifier le type

Normalement, les objets créés par script devraient utiliser des propriétés pour stocker des informations, car celles-ci sont automatiquement restaurées à l'ouverture du document.

Cependant, il arrive que la classe restitue des informations internes qui ne sont pas destinées à être modifiées, mais qu'il est utile d'inspecter.

Par exemple, la plupart des objets de l'atelier Draft configurent un attribut Type qui peut être utilisé pour déterminer le type d'objet utilisé.

class DraftObject:
    def __init__(self, obj, _type):
        self.Type = _type

    def dumps(self):
        return self.Type

    def loads(self, state):
        if state:
            self.Type = state

Tous les objets ont une propriété TypeId, mais pour les objets créés par script, cette propriété n'est pas utile car elle fait toujours référence à la classe C++ parente, par exemple, Part::Part2DObjectPython ou Part::FeaturePython. Par conséquent, le fait d'avoir cet attribut supplémentaire Proxy.Type dans la classe est utile pour traiter chaque objet d'une manière particulière.

Migration de l'objet

Les informations de version peuvent être stockées à l'intérieur de la classe afin de vérifier l'origine d'un objet.

class CustomObject:
    def __init__(self, obj, _type):
        self.Type = _type
        self.version = "0.18"

    def dumps(self):
        return self.Type, self.version

    def loads(self, state):
        if state:
            self.Type = state[0]
            self.version = state[1]

Si la structure de la classe change, c'est-à-dire si ses propriétés ou méthodes changent, sont renommées ou supprimées, nous pourrions tester l'attribut version afin de faire migrer l'ancien objet vers un nouvel ensemble de propriétés ou vers une nouvelle classe. Ceci peut être fait en implémentant la méthode onDocumentRestored, comme expliqué dans Migration d'objets créés par script.

class CustomObject:
    def onDocumentRestored(self, obj):
        if hasattr(obj.Proxy, "version") and obj.Proxy.version:
            if obj.Proxy.version == "0.18":
                self.migrate_from_018(obj)

    def migrate_from_018(self, obj):
        ...

Liens

  • Objets créés par script
  • Migration d'objets créés par script
  • Discussion sur le forum FreeCAD : Sérialisation des objets scripts : json ou pickle ?
  • obj.Proxy.Type est un dict, pas une chaîne de caractères, explication de dumps et loads dans le forum.
  • Le module Pickle dans la documentation Python.

Cette page est extraite de https://wiki.freecad.org/Scripted_objects_saving_attributes

Contactez-nous !
Forum GitHub Mastodon Matrix IRC Gitter.im Discord Reddit Twitter Facebook LinkedIn

© L'équipe FreeCAD. Crédits des images de la page d'accueil (de haut en bas) : ppemawm, r-frank, epileftric, regis, rider_mortagnais, bejant.

Ce projet est soutenu par : , KiCad Services Corp. et autres parrains

GitHubAméliorer cette page sur GitHub