0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022"""
0023base abstract class from which all geometric objects are derived
0024"""
0025
0026
0027from pygeo.base.support.pygeoconstants import BLACK
0028
0029
0030from pygeo.base.analytics.pygeomath import identity
0031
0032
0033elements=[]
0034
0035
0036freepoints=[]
0037
0038def register(element,args):
0039 """ recursive function called upom the initialization of geometric ojects,
0040 registering a direct or indirect dependance with movable points in a scene"""
0041
0042 import pygeo.base.abstracts._real as Real
0043 import pygeo.base.abstracts._complex as Complex
0044 import pygeo.base.abstracts._usphere as USphere
0045 for i in args:
0046 if (isinstance(i,Real._FreePosition)
0047 or isinstance(i,Complex._zFreePosition)
0048 or isinstance(i,USphere._uFreePosition)) :
0049 i._add_dependant(element)
0050 if hasattr(i,'args'):
0051 register(element,i.args)
0052
0053def get_args(args):
0054 """ a function to filter geometric objects (i.e. descendants of the Element class)
0055 from other arguments (e.g. numeric) that intialize an object"""
0056 e=[]
0057 for arg in args:
0058 if isinstance(arg,Element):
0059 e.append(arg)
0060 return e
0061
0062def method_get(sigs,args):
0063 """arguments to Element classes are tested against their constructor signature and
0064 returned ordered as per signature"""
0065
0066 def order(sig,_args):
0067 w=[]
0068 args=_args[:]
0069 for S in sig:
0070 v=[issubclass(a.__class__,S) for a in args]
0071 if 1 in v:
0072 w.append(args[v.index(1)])
0073 args.pop(v.index(1))
0074 return w
0075 args=list(args)
0076 for i in range(len(args)):
0077 if type(args[i])== int:
0078 args[i]=float(args[i])
0079 ret=[]
0080 for S in sigs:
0081 if len(args) == len(S):
0082 final_args = order(S,args)
0083 if len(final_args) == len(S):
0084 ret.append([final_args,sigs.index(S)])
0085 if ret:
0086 return max(ret)
0087 else:
0088 return None,None
0089
0090class Element(object):
0091 """
0092the abstract class from which all PyGeo geometric objects derive
0093"""
0094
0095 __opts__ = ["color","initcolor","trace","level",
0096 "texture","extend","povout","label","append","export"]
0097
0098 def __init__(self,*args,**kws):
0099 """ intialization of the common attributes of geometric objects to default
0100 values, overridden to the extent that avalable keyword arguemtns are provided"""
0101
0102 self.append = (kws.get("append",True))
0103
0104
0105
0106 for key in kws:
0107 if key not in self.__opts__:
0108 print 'WARNING "%s" not a valid keyword for initialization of %s' %(key,self.__class__.__name__)
0109
0110
0111
0112 self.Not_null=True
0113
0114
0115
0116 self.show=True
0117
0118
0119 self.color = (kws.get("color",BLACK))
0120
0121
0122
0123
0124 self.initcolor = self.color
0125
0126
0127
0128 self.trace=kws.get("trace",False)
0129
0130
0131
0132 self.level=kws.get("level",1)
0133
0134
0135
0136
0137 self.extend=kws.get("extend",False)
0138 self.export=kws.get("export",True)
0139
0140
0141
0142 self.texture=kws.get("texture",None)
0143
0144
0145 self.rend=[]
0146
0147
0148 self.visible= True
0149
0150
0151
0152 self.crend=[]
0153
0154
0155 self.rtrace=[]
0156
0157
0158 self.label=kws.get("label", None)
0159
0160
0161
0162 self.r_Flag=True
0163
0164
0165
0166 self.n_Flag=True
0167
0168
0169 self.init_draw=False
0170
0171 self.register=kws.get("register", True)
0172
0173 self.args=[]
0174
0175 if self.append:
0176 elements.append(self)
0177 self.args=get_args(args)
0178 register(self,self.args)
0179
0180
0181
0182 def __iter__(self):
0183 """ make all objects iterable, returning "self" in the simplest instance"""
0184
0185 all = [self] + self.rtrace
0186 for a in all:
0187 yield a
0188
0189 def __len__(self):
0190 """length of the iterable assocaited with the object"""
0191
0192 all = [self] + self.rtrace
0193 return len(all)
0194
0195 def update(self):
0196 """method that is called on change events, calling reoutines to find current
0197 position based on dependecies, current visibility status, etc."""
0198
0199 tflag = self.findSelf()
0200 if tflag <> self.r_Flag:
0201 self._togglenull()
0202 self.setshow()
0203 self.r_Flag =tflag
0204
0205 def findSelf(self):
0206 """ the function called to recalculate an objects postion at a change event,
0207 to be overridden in subclasses"""
0208
0209 return True
0210
0211 def rmatrix(self):
0212 """each object has a 4x4 matrix associated with it, representing the object's axis of
0213 rotation and translation from the origin. Needed for the implementation of the
0214 Projection class. Set to the identity matrix by default."""
0215
0216 return identity(4).astype('d')
0217
0218 def _allreal(self):
0219 """test whether any Elements on which there is a dependency
0220 have become 'null', i.e. not calculatable - .e.g, imaginary when
0221 working within real space"""
0222
0223 nflag = 0 not in [p.Not_null for p in self.args]
0224 if nflag <> self.n_Flag:
0225 if not nflag:
0226 if self.Not_null:
0227 self._setnull(True)
0228 else:
0229 self._setnull(False)
0230 self.n_Flag=nflag
0231
0232 def setshow(self):
0233 """check for change in visibiliy status and toggle
0234 visibility as necessary, reset change flag to 0 on
0235 effectuating change in visiblity"""
0236
0237 if self.Not_null and self.show:
0238 if not self.visible:
0239 for e in self:
0240 for r in e.rend:
0241 r.visible=True
0242 if self.label:
0243 self.lab.visible=True
0244 for c in self.crend:
0245 c.visible=True
0246 self.visible=True
0247 else:
0248 if self.visible:
0249 for e in self:
0250 for r in e.rend:
0251 r.visible=False
0252 if self.label:
0253 self.lab.visible=False
0254 for c in self.crend:
0255 c.visible=False
0256 self.visible=False
0257 self._redraw()
0258 if self.extend:
0259 self.setext()
0260
0261 def _togglenull(self):
0262 """ toggle the 'null' flag, indicating whether the current postion of the
0263 object's position is visible - e.g. is real when working in real space"""
0264
0265 if self.Not_null:
0266 self._setnull(True)
0267 else:
0268 self._setnull(False)
0269
0270 def _setnull(self,to_null=True):
0271 """ set object and the objects dependant on it to 'null' when
0272 its position cannot be made visible- e.g. imaginary when working in real
0273 space."""
0274
0275 if to_null:
0276 if self.Not_null:
0277 self.Not_null=False
0278 for d in self.deps:
0279 d.Not_null=False
0280 else:
0281 if not self.Not_null:
0282 self.Not_null=True
0283 for d in self.deps:
0284 d.Not_null=True
0285
0286 def init(self):
0287 """ method to be overridden for objects needing an supplementary initiliazation routine after
0288 the call to __init___"""
0289
0290 if self.level > 1:
0291 self.show=False
0292 if not self.init_draw:
0293 self.draw()
0294 if self.append:
0295 self.update()
0296
0297 def reset(self):
0298 """Routine to return Element to intial position.
0299 Default is to run update routine"""
0300
0301 self.update()
0302
0303 def reset_trace(self):
0304 """ method to be overridden to erase loci of objects that are traceable"""
0305
0306 pass
0307
0308 def reset_trace_curves(self):
0309 """ method to be overridden to erase curves traced by point objects"""
0310
0311 pass
0312
0313
0314
0315__author__ = "Arthur Siegel <ajsiegel@optonline.com>"
0316__date__ = "Date: 2006-02-02"
0317__revision__ = "Revision: a1"
0318__url__ = "http://sourceforge.net/projects/pygeo"
0319__license__ ="GPL <http://www.opensource.org/licenses/gpl-license.php>"