File size: 12,969 Bytes
985c397 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 | # SPDX-License-Identifier: LGPL-2.1-or-later
# FreeCAD module providing base classes for document objects and view provider
# (c) 2011 Werner Mayer LGPL
import FreeCAD
class DocumentObject(object):
"""The Document object is the base class for all FreeCAD objects."""
def __init__(self):
self.__object__=None
self.initialised=False
#------------------------------Methods for the user to override :
def execute(self):
"this method is executed on object creation and whenever the document is recomputed"
raise NotImplementedError("Not yet implemented")
def init(self):
#will be called just after object creation, you can use this for example to create properties
pass
def propertyChanged(self,prop):
#will be called each time a property is changed
pass
#--------------------------------
def __getattr__(self, attr):
if attr !="__object__" and hasattr(self.__object__,attr):
return getattr(self.__object__,attr)
else:
return object.__getattribute__(self,attr)
def __setattr__(self, attr, value):
if attr !="__object__" and hasattr(self.__object__,attr):
setattr(self.__object__,attr,value)
else:
object.__setattr__(self,attr,value)
def onChanged(self,prop):
if prop=="Proxy":
#recreate the functions in the __object__
d = self.__class__.__dict__
for key in d:
item = d[key]
#check if the function is valid
if hasattr(item, '__call__') and key!="onChanged" and key!="execute" and key!="init" and key[0]!="_":
#check if the function doesn't already exist in the object:
if not(hasattr(self.__object__,key)):
#add a link to the Proxy function in the __object__ :
self.addProperty("App::PropertyPythonObject", key, "", "",2)
setattr(self.__object__,key,getattr(self,key))
else:
FreeCAD.Console.PrintWarning('!!! The function : "'+key+'" already exist in the object, cannot override. !!!\n')
#call the init function
if hasattr(self,'initialised'):
if self.initialised==False:
self.init()
self.initialised = True
self.propertyChanged(prop)
def addProperty(self,typ,name='',group='',doc='',attr=0,readonly=False,hidden=False):
"adds a new property to this object"
return self.__object__.addProperty(typ,name,group,doc,attr,readonly,hidden)
def supportedProperties(self):
"lists the property types supported by this object"
return self.__object__.supportedProperties()
def isDerivedFrom(self, obj):
"""returns True if this object is derived from the given C++ class, for
example Part::Feature"""
return self.__object__.isDerivedFrom(obj)
def getAllDerivedFrom(self):
"returns all parent C++ classes of this object"
return self.__object__.getAllDerivedFrom()
def getProperty(self,attr):
"returns the value of a given property"
return self.__object__.getPropertyByName(attr)
def getTypeOfProperty(self,attr):
"returns the type of a given property"
return self.__object__.getTypeOfProperty(attr)
def getGroupOfProperty(self,attr):
"returns the group of a given property"
return self.__object__.getGroupOfProperty(attr)
def getDocumentationOfProperty(self,attr):
"returns the documentation string of a given property"
return self.__object__.getDocumentationOfProperty(attr)
def getEnumerationsOfProperty(self,attr):
"returns the documentation string of a given property"
return self.__object__.getEnumerationsOfProperty(attr)
def touch(self):
"marks this object to be recomputed"
return self.__object__.touch()
def purgeTouched(self):
"removes the to-be-recomputed flag of this object"
return self.__object__.purgeTouched()
def __setstate__(self,value):
"""allows saving custom attributes of this object as strings, so
they can be saved when saving the FreeCAD document"""
return None
def __getstate__(self):
"""reads values previously saved with __setstate__()"""
return None
@property
def PropertiesList(self):
"lists the current properties of this object"
return self.__object__.PropertiesList
@property
def Type(self):
"shows the C++ class of this object"
return self.__object__.Type
@property
def Module(self):
"gives the module this object is defined in"
return self.__object__.Module
@property
def Content(self):
"""shows the contents of the properties of this object as an xml string.
This is the content that is saved when the file is saved by FreeCAD"""
return self.__object__.Content
@property
def MemSize(self):
"shows the amount of memory this object uses"
return self.__object__.MemSize
@property
def Name(self):
"the name ofthis object, unique in the FreeCAD document"
return self.__object__.Name
@property
def Document(self):
"the document this object is part of"
return self.__object__.Document
@property
def State(self):
"shows if this object is valid (presents no errors)"
return self.__object__.State
@property
def ViewObject(self):
return self.__object__.ViewObject
@ViewObject.setter
def ViewObject(self,value):
"""returns or sets the ViewObject associated with this object. Returns
None if FreeCAD is running in console mode"""
self.__object__.ViewObject=value
@property
def InList(self):
"lists the parents of this object"
return self.__object__.InList
@property
def OutList(self):
"lists the children of this object"
return self.__object__.OutList
class ViewProvider(object):
"""The ViewProvider is the counterpart of the DocumentObject in
the GUI space. It is only present when FreeCAD runs in GUI mode.
It contains all that is needed to represent the DocumentObject in
the 3D view and the FreeCAD interface"""
def __init__(self):
self.__vobject__=None
#def getIcon(self):
# return ""
#def claimChildren(self):
# return self.__vobject__.Object.OutList
#def setEdit(self,mode):
# return False
#def unsetEdit(self,mode):
# return False
#def attach(self):
# return None
#def updateData(self, prop):
# return None
#def onChanged(self, prop):
# return None
def addDisplayMode(self,node,mode):
"adds a coin node as a display mode to this object"
self.__vobject__.addDisplayMode(node,mode)
#def getDefaultDisplayMode(self):
# return ""
#def getDisplayModes(self):
# return []
#def setDisplayMode(self,mode):
# return mode
def addProperty(self,type,name='',group='',doc='',attr=0,readonly=False,hidden=False):
"adds a new property to this object"
self.__vobject__.addProperty(type,name,group,doc,attr,readonly,hidden)
def update(self):
"this method is executed whenever any of the properties of this ViewProvider changes"
self.__vobject__.update()
def show(self):
"switches this object to visible"
self.__vobject__.show()
def hide(self):
"switches this object to invisible"
self.__vobject__.hide()
def isVisible(self):
"shows whether this object is visible or invisible"
return self.__vobject__.isVisible()
def toString(self):
"returns a string representation of the coin node of this object"
return self.__vobject__.toString()
def setTransformation(self,trsf):
"defines a transformation for this object"
return self.__vobject__.setTransformation(trsf)
def supportedProperties(self):
"lists the property types this ViewProvider supports"
return self.__vobject__.supportedProperties()
def isDerivedFrom(self, obj):
"""returns True if this object is derived from the given C++ class, for
example Part::Feature"""
return self.__vobject__.isDerivedFrom(obj)
def getAllDerivedFrom(self):
"returns all parent C++ classes of this object"
return self.__vobject__.getAllDerivedFrom()
def getProperty(self,attr):
"returns the value of a given property"
return self.__vobject__.getPropertyByName(attr)
def getTypeOfProperty(self,attr):
"returns the type of a given property"
return self.__vobject__.getTypeOfProperty(attr)
def getGroupOfProperty(self,attr):
"returns the group of a given property"
return self.__vobject__.getGroupOfProperty(attr)
def getDocumentationOfProperty(self,attr):
"returns the documentation string of a given property"
return self.__vobject__.getDocumentationOfProperty(attr)
def __setstate__(self,value):
"""allows saving custom attributes of this object as strings, so
they can be saved when saving the FreeCAD document"""
return None
def __getstate__(self):
"""reads values previously saved with __setstate__()"""
return None
@property
def Annotation(self):
"returns the Annotation coin node of this object"
return self.__vobject__.Annotation
@property
def RootNode(self):
"returns the Root coin node of this object"
return self.__vobject__.RootNode
@property
def DisplayModes(self):
"lists the display modes of this object"
return self.__vobject__.listDisplayModes()
@property
def PropertiesList(self):
"lists the current properties of this object"
return self.__vobject__.PropertiesList
@property
def Type(self):
"shows the C++ class of this object"
return self.__vobject__.Type
@property
def Module(self):
"gives the module this object is defined in"
return self.__vobject__.Module
@property
def Content(self):
"""shows the contents of the properties of this object as an xml string.
This is the content that is saved when the file is saved by FreeCAD"""
return self.__vobject__.Content
@property
def MemSize(self):
"shows the amount of memory this object uses"
return self.__vobject__.MemSize
@property
def Object(self):
"returns the DocumentObject this ViewProvider is associated to"
return self.__vobject__.Object
#Example :
import Part
class Box(DocumentObject):
#type :
type = "Part::FeaturePython"
#-----------------------------INIT----------------------------------------
def init(self):
self.addProperty("App::PropertyLength","Length","Box","Length of the box", locked=True).Length=1.0
self.addProperty("App::PropertyLength","Width","Box","Width of the box", locked=True).Width=1.0
self.addProperty("App::PropertyLength","Height","Box", "Height of the box", locked=True).Height=1.0
#-----------------------------BEHAVIOR------------------------------------
def propertyChanged(self,prop):
FreeCAD.Console.PrintMessage("Box property changed : "+ prop+ "\n")
if prop == "Length" or prop == "Width" or prop == "Height":
self._recomputeShape()
def execute(self):
FreeCAD.Console.PrintMessage("Recompute Python Box feature\n")
self._recomputeShape()
#---------------------------PUBLIC FUNCTIONS-------------------------------
#These functions will be present in the object
def customFunctionSetLength(self,attr):
self.Length = attr
self._privateFunctionExample(attr)
#---------------------------PRIVATE FUNCTIONS------------------------------
#These function won't be present in the object (begin with '_')
def _privateFunctionExample(self,attr):
FreeCAD.Console.PrintMessage("The length : "+str(attr)+"\n")
def _recomputeShape(self):
if hasattr(self,"Length") and hasattr(self,"Width") and hasattr(self,"Height"):
self.Shape = Part.makeBox(self.Length,self.Width,self.Height)
def makeBox():
FreeCAD.newDocument()
box = FreeCAD.ActiveDocument.addObject(Box.type,"MyBox",Box(),None)
box.customFunctionSetLength(4)
|