/[escript]/branches/arrexp_2137_win_merge/pycad/py_src/primitives.py
ViewVC logotype

Diff of /branches/arrexp_2137_win_merge/pycad/py_src/primitives.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2213 by jfenwick, Wed Jan 14 00:23:39 2009 UTC revision 2214 by jfenwick, Wed Jan 14 03:39:41 2009 UTC
# Line 39  try: Line 39  try:
39     import numpy     import numpy
40     numpyImported=True     numpyImported=True
41  except:  except:
42     numpyImported=False       numpyImported=False
43    
44  import numarray  import numarray
45  from transformations import _TYPE, Translation, Dilation, Transformation  from transformations import _TYPE, Translation, Dilation, Transformation
# Line 48  from math import sqrt Line 48  from math import sqrt
48    
49  def resetGlobalPrimitiveIdCounter():  def resetGlobalPrimitiveIdCounter():
50     """     """
51     initializes the global primitive ID counter     Initializes the global primitive ID counter.
52     """     """
53     global global_primitive_id_counter     global global_primitive_id_counter
54     global_primitive_id_counter=1     global_primitive_id_counter=1
55    
56  def setToleranceForColocation(tol=1.e-11):  def setToleranceForColocation(tol=1.e-11):
57     """     """
58     set the global tolerance for colocation checks to tol     Sets the global tolerance for colocation checks to C{tol}.
59     """     """
60     global global_tolerance_for_colocation     global global_tolerance_for_colocation
61     global_tolerance_for_colocation=tol     global_tolerance_for_colocation=tol
62    
63  def getToleranceForColocation():  def getToleranceForColocation():
64     """     """
65     returns the global tolerance for colocation checks     Returns the global tolerance for colocation checks.
66     """     """
67     return global_tolerance_for_colocation     return global_tolerance_for_colocation
68    
# Line 72  setToleranceForColocation() Line 72  setToleranceForColocation()
72    
73  class PrimitiveBase(object):  class PrimitiveBase(object):
74      """      """
75      template for a set of primitives      Template for a set of primitives.
76      """      """
77      def __init__(self):      def __init__(self):
78           """
79           Initializes the PrimitiveBase instance object.
80         """         """
        initializes PrimitiveBase instance object with id  
        """  
81         pass         pass
82    
83      def __cmp__(self,other):      def __cmp__(self,other):
84         """         """
85         compares object with other by comparing the absolute value of the ID         Compares object with other by comparing the absolute value of the ID.
86         """         """
87         if isinstance(other, PrimitiveBase):         if isinstance(other, PrimitiveBase):
88             return cmp(self.getID(),other.getID())             return cmp(self.getID(),other.getID())
89         else:         else:
90             return False             return False
91    
92      def getConstructionPoints(self):      def getConstructionPoints(self):
93          """          """
94          returns the points used to construct the primitive          Returns the points used to construct the primitive.
95          """          """
96          out=[]          out=[]
97          for i in self.getPrimitives():          for i in self.getPrimitives():
98             if isinstance(i,Point): out.append(i)             if isinstance(i,Point): out.append(i)
99          return out          return out
100    
101      def getPrimitives(self):      def getPrimitives(self):
102          """          """
103          returns a list of primitives used to construct the primitive with no double entries          Returns a list of primitives used to construct the primitive with no
104            double entries.
105          """          """
106          out=[]          out=[]
107          for p in self.collectPrimitiveBases():          for p in self.collectPrimitiveBases():
# Line 108  class PrimitiveBase(object): Line 110  class PrimitiveBase(object):
110    
111      def copy(self):      def copy(self):
112         """         """
113         returns a deep copy of the object         Returns a deep copy of the object.
114         """         """
115         return self.substitute({})         return self.substitute({})
116    
117      def modifyBy(self,transformation):      def modifyBy(self,transformation):
118         """         """
119         modifies the coordinates by applying a transformation         Modifies the coordinates by applying a transformation.
120         """         """
121         for p in self.getConstructionPoints(): p.modifyBy(transformation)         for p in self.getConstructionPoints(): p.modifyBy(transformation)
122    
123      def __add__(self,other):      def __add__(self,other):
124          """          """
125          returns a new object shifted by other          Returns a new object shifted by C{other}.
126          """          """
127          return self.apply(Translation(numarray.array(other,_TYPE)))          return self.apply(Translation(numarray.array(other,_TYPE)))
128    
129      def __sub__(self,other):      def __sub__(self,other):
130          """          """
131          returns a new object shifted by other          Returns a new object shifted by C{-other}.
132          """          """
133          return self.apply(Translation(-numarray.array(other,_TYPE)))          return self.apply(Translation(-numarray.array(other,_TYPE)))
134    
135      def __iadd__(self,other):      def __iadd__(self,other):
136          """          """
137          shifts the point by other          Shifts the point inplace by C{other}.
138          """          """
139          self.modifyBy(Translation(numarray.array(other,_TYPE)))          self.modifyBy(Translation(numarray.array(other,_TYPE)))
140          return self          return self
141    
142      def __isub__(self,other):      def __isub__(self,other):
143          """          """
144          shifts the point by -other          Shifts the point inplace by C{-other}.
145          """          """
146          self.modifyBy(Translation(-numarray.array(other,_TYPE)))          self.modifyBy(Translation(-numarray.array(other,_TYPE)))
147          return self          return self
148    
149      def __imul__(self,other):      def __imul__(self,other):
150          """          """
151          modifies object by applying L{Transformation} other. If other is not a L{Transformation} it will try convert it.          Modifies object by applying L{Transformation} C{other}. If C{other}
152            is not a L{Transformation} it is first tried to be converted.
153          """          """
154          if isinstance(other,int) or isinstance(other,float):          if isinstance(other,int) or isinstance(other,float):
155              trafo=Dilation(other)              trafo=Dilation(other)
# Line 155  class PrimitiveBase(object): Line 158  class PrimitiveBase(object):
158          elif isinstance(other,Transformation):          elif isinstance(other,Transformation):
159              trafo=other              trafo=other
160          else:          else:
161              raise TypeError, "cannot convert argument to Trnsformation class object."              raise TypeError, "cannot convert argument to a Transformation class object."
162          self.modifyBy(trafo)          self.modifyBy(trafo)
163          return self          return self
164    
165      def __rmul__(self,other):      def __rmul__(self,other):
166          """          """
167          applies L{Transformation} other to object. If other is not a L{Transformation} it will try convert it.          Applies L{Transformation} C{other} to object. If C{other} is not a
168            L{Transformation} it is first tried to be converted.
169          """          """
170          if isinstance(other,int) or isinstance(other,float):          if isinstance(other,int) or isinstance(other,float):
171              trafo=Dilation(other)              trafo=Dilation(other)
# Line 176  class PrimitiveBase(object): Line 180  class PrimitiveBase(object):
180    
181      def setLocalScale(self,factor=1.):      def setLocalScale(self,factor=1.):
182         """         """
183         sets the local refinement factor         Sets the local refinement factor.
184         """         """
185         for p in self.getConstructionPoints(): p.setLocalScale(factor)         for p in self.getConstructionPoints(): p.setLocalScale(factor)
186    
187      def apply(self,transformation):      def apply(self,transformation):
188          """          """
189          returns a new object by applying the transformation          Returns a new object by applying the transformation.
190          """          """
191          out=self.copy()          out=self.copy()
192          out.modifyBy(transformation)          out.modifyBy(transformation)
# Line 190  class PrimitiveBase(object): Line 194  class PrimitiveBase(object):
194    
195  class Primitive(object):  class Primitive(object):
196      """      """
197      A general primitive      Class that represents a general primitive.
198      """      """
199      def __init__(self):      def __init__(self):
200           """
201           Initializes the Primitive instance object with a unique ID.
202         """         """
        initializes PrimitiveBase instance object with id  
        """  
203         global global_primitive_id_counter         global global_primitive_id_counter
204         self.__ID=global_primitive_id_counter         self.__ID=global_primitive_id_counter
205         global_primitive_id_counter+=1         global_primitive_id_counter+=1
206    
207      def getID(self):      def getID(self):
208         """         """
209         returns the primitive ID         Returns the primitive ID.
210         """         """
211         return self.__ID         return self.__ID
212    
213      def getDirectedID(self):      def getDirectedID(self):
214          """          """
215          returns the primitive ID where a negative signs means that the reversed ordring is used.          Returns the primitive ID where a negative sign means that reversed
216            ordering is used.
217          """          """
218          return self.getID()          return self.getID()
219    
220      def __repr__(self):      def __repr__(self):
221         return "%s(%s)"%(self.__class__.__name__,self.getID())          return "%s(%s)"%(self.__class__.__name__,self.getID())
222    
223      def getUnderlyingPrimitive(self):      def getUnderlyingPrimitive(self):
224          """          """
225          returns the underlying primitive          Returns the underlying primitive.
226          """          """
227          return self          return self
228    
229      def hasSameOrientation(self,other):      def hasSameOrientation(self,other):
230          """          """
231          returns True if other is the same primitive and has the same orientation          Returns True if C{other} is the same primitive and has the same
232            orientation, False otherwise.
233          """          """
234          return self == other and isinstance(other,Primitive)          return self == other and isinstance(other,Primitive)
235    
236      def __neg__(self):      def __neg__(self):
237          """          """
238          returns a view onto the curve with reversed ordering          Returns a view onto the curve with reversed ordering.
239    
240          @note: this class is overwritten by subclass          @note: This method is overwritten by subclasses.
241          """          """
242          raise NotImplementedError("__neg__ is not implemented.")          raise NotImplementedError("__neg__ is not implemented.")
243    
244      def substitute(self,sub_dict):      def substitute(self,sub_dict):
245          """          """
246          returns a copy of self with substitutes for the primitives used to construct it given by the dictionary C{sub_dict}.          Returns a copy of self with substitutes for the primitives used to
247          If a substitute for the object is given by C{sub_dict} the value is returned, otherwise a new instance          construct it given by the dictionary C{sub_dict}. If a substitute for
248          with substituted arguments is returned.          the object is given by C{sub_dict} the value is returned, otherwise a
249            new instance with substituted arguments is returned.
250    
251          @note: this class is overwritten by subclass          @note: This method is overwritten by subclasses.
252          """          """
253          raise NotImplementedError("substitute is not implemented.")          raise NotImplementedError("substitute is not implemented.")
254    
255      def collectPrimitiveBases(self):      def collectPrimitiveBases(self):
256          """          """
257          returns a list of primitives used to construct the primitive. It may contain primitives twice          Returns a list of primitives used to construct the primitive. It may
258                    contain primitives twice.
259          @note: this class is overwritten by subclass  
260            @note: This method is overwritten by subclasses.
261          """          """
262          raise NotImplementedError("collectPrimitiveBases is not implemented.")          raise NotImplementedError("collectPrimitiveBases is not implemented.")
263    
264      def isColocated(self,primitive):      def isColocated(self,primitive):
265         """         """
266         returns True is the two primitives are located at the smae position         Rreturns True if the two primitives are located at the same position.
267    
268         @note: this class is overwritten by subclass         @note: This method is overwritten by subclasses.
269         """         """
270         raise NotImplementedError("isColocated is not implemented.")         raise NotImplementedError("isColocated is not implemented.")
271    
272    
273  class ReversePrimitive(object):  class ReversePrimitive(object):
274      """      """
275      A view onto a primitive creating an reverse orientation      A view onto a primitive creating a reverse orientation.
276      """      """
277      def __init__(self,primitive):      def __init__(self,primitive):
278           """
279           Instantiates a view onto C{primitive}.
280         """         """
        instantiate a view onto primitve  
        """  
281         if not isinstance(primitive, Primitive):         if not isinstance(primitive, Primitive):
282             raise ValueError("argument needs to be a Primitive class object.")             raise ValueError("argument needs to be a Primitive class object.")
283         self.__primitive=primitive         self.__primitive=primitive
284    
285      def getID(self):      def getID(self):
286         """         """
287         returns the primitive ID         Returns the primitive ID.
288         """         """
289         return self.__primitive.getID()         return self.__primitive.getID()
290    
291      def getUnderlyingPrimitive(self):      def getUnderlyingPrimitive(self):
292          """          """
293          returns the underlying primitive          Returns the underlying primitive.
294          """          """
295          return self.__primitive          return self.__primitive
296    
297      def hasSameOrientation(self,other):      def hasSameOrientation(self,other):
298          """          """
299          returns True if other is the same primitive and has the same orientation          Returns True if C{other} is the same primitive and has the same
300            orientation as self.
301          """          """
302          return self == other and isinstance(other,ReversePrimitive)          return self == other and isinstance(other,ReversePrimitive)
303    
# Line 296  class ReversePrimitive(object): Line 306  class ReversePrimitive(object):
306    
307      def getDirectedID(self):      def getDirectedID(self):
308          """          """
309          returns the primitive ID where a negative signs means that the reversed ordring is used.          Returns the primitive ID where a negative signs means that reversed
310            ordering is used.
311          """          """
312          return -self.__primitive.getID()          return -self.__primitive.getID()
313    
314      def substitute(self,sub_dict):      def substitute(self,sub_dict):
315          """          """
316          returns a copy of self with substitutes for the primitives used to construct it given by the dictionary C{sub_dict}.          Returns a copy of self with substitutes for the primitives used to
317          If a substitute for the object is given by C{sub_dict} the value is returned, otherwise a new instance          construct it given by the dictionary C{sub_dict}. If a substitute for
318          with substituted arguments is returned.          the object is given by C{sub_dict} the value is returned, otherwise a
319            new instance with substituted arguments is returned.
320          """          """
321          if not sub_dict.has_key(self):          if not sub_dict.has_key(self):
322              sub_dict[self]=-self.getUnderlyingPrimitive().substitute(sub_dict)              sub_dict[self]=-self.getUnderlyingPrimitive().substitute(sub_dict)
323          return sub_dict[self]          return sub_dict[self]
324                
325      def __neg__(self):      def __neg__(self):
326            """            """
327            returns a view onto the curve with reversed ordering            Returns a view onto the curve with reversed ordering.
328            """            """
329            return self.__primitive            return self.__primitive
330    
331      def collectPrimitiveBases(self):      def collectPrimitiveBases(self):
332          """          """
333          returns a list of primitives used to construct the primitive. It may contain primitives twice          Returns a list of primitives used to construct the primitive. It may
334            contain primitives twice.
335          """          """
336          return self.__primitive.collectPrimitiveBases()          return self.__primitive.collectPrimitiveBases()
337    
338      def isColocated(self,primitive):      def isColocated(self,primitive):
339         """         """
340         returns True is the two primitives are located at the smae position         Returns True if the two primitives are located at the same position.
341    
342         @note: this class is overwritten by subclass         @note: This method is overwritten by subclasses.
343         """         """
344         return self.__primitive.isColocated(primitive)         return self.__primitive.isColocated(primitive)
345    
346  class Point(Primitive, PrimitiveBase):  class Point(Primitive, PrimitiveBase):
347      """      """
348      a three dimensional point      A three-dimensional point.
349      """      """
350      def __init__(self,x=0.,y=0.,z=0.,local_scale=1.):      def __init__(self,x=0.,y=0.,z=0.,local_scale=1.):
351           """
352           Creates a point with coordinates C{x}, C{y}, C{z} with the local
353           refinement factor C{local_scale}.
354         """         """
        creates a point with coorinates x,y,z with the local refinement factor local_scale  
        """  
355         PrimitiveBase.__init__(self)         PrimitiveBase.__init__(self)
356         Primitive.__init__(self)         Primitive.__init__(self)
357         self.setCoordinates(numarray.array([x,y,z],_TYPE))         self.setCoordinates(numarray.array([x,y,z],_TYPE))
# Line 345  class Point(Primitive, PrimitiveBase): Line 359  class Point(Primitive, PrimitiveBase):
359    
360      def setLocalScale(self,factor=1.):      def setLocalScale(self,factor=1.):
361         """         """
362         sets the local refinement factor         Sets the local refinement factor.
363         """         """
364         if factor<=0.:         if factor<=0.:
365            raise ValueError("scaling factor must be positive.")            raise ValueError("scaling factor must be positive.")
# Line 353  class Point(Primitive, PrimitiveBase): Line 367  class Point(Primitive, PrimitiveBase):
367    
368      def getLocalScale(self):      def getLocalScale(self):
369         """         """
370         returns the local refinement factor         Returns the local refinement factor.
371         """         """
372         return self.__local_scale         return self.__local_scale
373    
374      def getCoordinates(self):      def getCoordinates(self):
375         """         """
376         returns the coodinates of the point as L{numarray.NumArray} object         Returns the coodinates of the point as a C{numarray.NumArray} object.
377         """         """
378         return self._x         return self._x
379    
380      def setCoordinates(self,x):      def setCoordinates(self,x):
381         """         """
382         returns the coodinates of the point as L{numarray.NumArray} object         Sets the coodinates of the point from a C{numarray.NumArray} object C{x}.
383         """         """
384         if not isinstance(x, numarray.NumArray):         if not isinstance(x, numarray.NumArray):
385            self._x=numarray.array(x,_TYPE)            self._x=numarray.array(x,_TYPE)
# Line 372  class Point(Primitive, PrimitiveBase): Line 388  class Point(Primitive, PrimitiveBase):
388    
389      def collectPrimitiveBases(self):      def collectPrimitiveBases(self):
390         """         """
391         returns primitives used to construct the primitive         Returns primitives used to construct the primitive.
392         """         """
393         return [self]         return [self]
394    
395      def isColocated(self,primitive):      def isColocated(self,primitive):
396         """         """
397         returns True if L{Point} primitive is colocation (same coordinates)         Returns True if the L{Point} C{primitive} is colocated (has the same
398         that means if |self-primitive| <= tol * max(|self|,|primitive|)         coordinates) with self. That is, if
399           M{|self-primitive| <= tol * max(|self|,|primitive|)}.
400         """         """
401         if isinstance(primitive,Point):         if isinstance(primitive,Point):
402            primitive=primitive.getCoordinates()            primitive=primitive.getCoordinates()
# Line 394  class Point(Primitive, PrimitiveBase): Line 411  class Point(Primitive, PrimitiveBase):
411    
412      def substitute(self,sub_dict):      def substitute(self,sub_dict):
413          """          """
414          returns a copy of self with substitutes for the primitives used to construct it given by the dictionary C{sub_dict}.          Returns a copy of self with substitutes for the primitives used to
415          If a substitute for the object is given by C{sub_dict} the value is returned, otherwise a new instance          construct it given by the dictionary C{sub_dict}. If a substitute for
416          with substituted arguments is returned.          the object is given by C{sub_dict} the value is returned, otherwise a
417            new instance with substituted arguments is returned.
418          """          """
419          if not sub_dict.has_key(self):          if not sub_dict.has_key(self):
420             c=self.getCoordinates()             c=self.getCoordinates()
# Line 405  class Point(Primitive, PrimitiveBase): Line 423  class Point(Primitive, PrimitiveBase):
423    
424      def modifyBy(self,transformation):      def modifyBy(self,transformation):
425          """          """
426          modifies the coordinates by applying a transformation          Modifies the coordinates by applying the given transformation.
427          """          """
428          self.setCoordinates(transformation(self.getCoordinates()))          self.setCoordinates(transformation(self.getCoordinates()))
429    
   
430      def __neg__(self):      def __neg__(self):
431          """          """
432          returns a view of the object with reverse orientiention. As a point has no direction the object itself is returned.          Returns a view of the object with reverse orientation. As a point has
433            no direction the object itself is returned.
434          """          """
435          return self          return self
436          
437  class Manifold1D(PrimitiveBase):  class Manifold1D(PrimitiveBase):
438      """      """
439      general one-dimensional minifold in 3D defined by a start and end point.      General one-dimensional manifold in 1D defined by a start and end point.
440      """      """
441      def __init__(self):      def __init__(self):
442          """          """
443          create a one-dimensional manifold          Initializes the one-dimensional manifold.
444          """          """
445          PrimitiveBase.__init__(self)          PrimitiveBase.__init__(self)
446    
447      def getStartPoint(self):      def getStartPoint(self):
448           """           """
449           returns start point           Returns the start point.
450           """           """
451           raise NotImplementedError()           raise NotImplementedError()
452    
453      def getEndPoint(self):      def getEndPoint(self):
454           """           """
455           returns end point           Returns the end point.
456           """           """
457           raise NotImplementedError()           raise NotImplementedError()
458    
459      def getBoundary(self):      def getBoundary(self):
460          """          """
461          returns a list of the zero-dimensional manifolds forming the boundary of the curve          Returns a list of the zero-dimensional manifolds forming the boundary
462            of the curve.
463          """          """
464          return [ self.getStartPoint(), self.getEndPoint()]          return [ self.getStartPoint(), self.getEndPoint()]
465    
466  class CurveBase(Manifold1D):  class CurveBase(Manifold1D):
467      """      """
468      A Curve is defined by a set of control points      Base class for curves. A Curve is defined by a set of control points.
469      """      """
470      def __init__(self):      def __init__(self):
471            """          """
472            create curve          Initializes the curve.
473            """          """
474            Manifold1D.__init__(self)          Manifold1D.__init__(self)
475    
476      def __len__(self):      def __len__(self):
477            """          """
478            returns the number of control points          Returns the number of control points.
479            """          """
480            return len(self.getControlPoints())          return len(self.getControlPoints())
481    
482      def getStartPoint(self):      def getStartPoint(self):
483           """          """
484           returns start point          Returns the start point.
485           """          """
486           return self.getControlPoints()[0]          return self.getControlPoints()[0]
487    
488      def getEndPoint(self):      def getEndPoint(self):
489           """          """
490           returns end point          Returns the end point.
491           """          """
492           return self.getControlPoints()[-1]          return self.getControlPoints()[-1]
493    
494      def getControlPoints(self):      def getControlPoints(self):
495           """          """
496           returns a list of the points          Returns a list of the points.
497           """          """
498           raise NotImplementedError()          raise NotImplementedError()
499    
500  class Curve(CurveBase, Primitive):  class Curve(CurveBase, Primitive):
501      """      """
502      a curve defined through a list of control points.      A curve defined through a list of control points.
503      """      """
504      def __init__(self,*points):      def __init__(self,*points):
505         """         """
506         defines a curve form control points         Defines a curve from control points given by C{points}.
507         """         """
508         if len(points)<2:         if len(points)<2:
509             raise ValueError("Curve needs at least two points")             raise ValueError("Curve needs at least two points")
# Line 496  class Curve(CurveBase, Primitive): Line 516  class Curve(CurveBase, Primitive):
516         Primitive.__init__(self)         Primitive.__init__(self)
517    
518      def getControlPoints(self):      def getControlPoints(self):
519           """          """
520           returns a list of the points          Returns a list of the points.
521           """          """
522           return self.__points          return self.__points
523          
524      def __neg__(self):      def __neg__(self):
525            """          """
526            returns a view onto the curve with reversed ordering          Returns a view onto the curve with reversed ordering.
527            """          """
528            return ReverseCurve(self)          return ReverseCurve(self)
529    
530      def substitute(self,sub_dict):      def substitute(self,sub_dict):
531          """          """
532          returns a copy of self with substitutes for the primitives used to construct it given by the dictionary C{sub_dict}.          Returns a copy of self with substitutes for the primitives used to
533          If a substitute for the object is given by C{sub_dict} the value is returned, otherwise a new instance          construct it given by the dictionary C{sub_dict}. If a substitute for
534          with substituted arguments is returned.          the object is given by C{sub_dict} the value is returned, otherwise a
535            new instance with substituted arguments is returned.
536          """          """
537          if not sub_dict.has_key(self):          if not sub_dict.has_key(self):
538              new_p=[]              new_p=[]
# Line 521  class Curve(CurveBase, Primitive): Line 542  class Curve(CurveBase, Primitive):
542    
543      def collectPrimitiveBases(self):      def collectPrimitiveBases(self):
544         """         """
545         returns primitives used to construct the Curve         Returns the primitives used to construct the curve.
546         """         """
547         out=[self]         out=[self]
548         for p in self.getControlPoints(): out+=p.collectPrimitiveBases()         for p in self.getControlPoints(): out+=p.collectPrimitiveBases()
# Line 529  class Curve(CurveBase, Primitive): Line 550  class Curve(CurveBase, Primitive):
550    
551      def isColocated(self,primitive):      def isColocated(self,primitive):
552         """         """
553         returns True curves are on the same position         Returns True if curves are at the same position.
554         """         """
555         if hasattr(primitive,"getUnderlyingPrimitive"):         if hasattr(primitive,"getUnderlyingPrimitive"):
556           if isinstance(primitive.getUnderlyingPrimitive(),self.__class__):           if isinstance(primitive.getUnderlyingPrimitive(),self.__class__):
557             if len(primitive) == len(self):             if len(primitive) == len(self):
558               cp0=self.getControlPoints()               cp0=self.getControlPoints()
559               cp1=primitive.getControlPoints()               cp1=primitive.getControlPoints()
# Line 550  class Curve(CurveBase, Primitive): Line 571  class Curve(CurveBase, Primitive):
571    
572  class ReverseCurve(CurveBase, ReversePrimitive):  class ReverseCurve(CurveBase, ReversePrimitive):
573      """      """
574      a curve defined through a list of control points.      A curve defined through a list of control points.
575      """      """
576      def __init__(self,curve):      def __init__(self,curve):
577         """         """
578         defines a curve form control points         Defines a curve from control points.
579         """         """
580         if not isinstance(curve, Curve):         if not isinstance(curve, Curve):
581             raise TypeError("ReverseCurve needs to be an instance of Curve")             raise TypeError("ReverseCurve needs to be an instance of Curve")
# Line 563  class ReverseCurve(CurveBase, ReversePri Line 584  class ReverseCurve(CurveBase, ReversePri
584    
585      def getControlPoints(self):      def getControlPoints(self):
586           """           """
587           returns a list of the points           Returns a list of the points.
588           """           """
589           out=[p for p in self.getUnderlyingPrimitive().getControlPoints()]           out=[p for p in self.getUnderlyingPrimitive().getControlPoints()]
590           out.reverse()           out.reverse()
# Line 571  class ReverseCurve(CurveBase, ReversePri Line 592  class ReverseCurve(CurveBase, ReversePri
592    
593  class Spline(Curve):  class Spline(Curve):
594      """      """
595      a spline curve defined through a list of control points.      A spline curve defined through a list of control points.
596      """      """
597      pass      pass
598    
599  class BezierCurve(Curve):  class BezierCurve(Curve):
600      """      """
601      a Bezier curve      A Bezier curve.
602      """      """
603      pass      pass
604    
605  class BSpline(Curve):  class BSpline(Curve):
606      """      """
607      a BSpline curve. Control points may be repeated.      A BSpline curve. Control points may be repeated.
608      """      """
609      pass      pass
610    
611  class Line(Curve):  class Line(Curve):
612      """      """
613      a line is defined by two pointDirecteds      A line is defined by two points.
614      """      """
615      def __init__(self,*points):      def __init__(self,*points):
616          """          """
617          defines a line with start and end point          Defines a line with start and end point.
618          """          """
619          if len(points)!=2:          if len(points)!=2:
620             raise TypeError("Line needs two points")             raise TypeError("Line needs two points")
621          Curve.__init__(self,*points)          Curve.__init__(self,*points)
622    
623  class ArcBase(Manifold1D):  class ArcBase(Manifold1D):
624        """
625        Base class for arcs.
626        """
627      def __init__(self):      def __init__(self):
628            """            """
629            create curve            Initializes the arc.
630            """            """
631            Manifold1D.__init__(self)            Manifold1D.__init__(self)
632    
633      def collectPrimitiveBases(self):      def collectPrimitiveBases(self):
634         """         """
635         returns the primitives used to construct the Curve         Returns the primitives used to construct the Arc.
636         """         """
637         out=[self]         out=[self]
638         out+=self.getStartPoint().collectPrimitiveBases()         out+=self.getStartPoint().collectPrimitiveBases()
# Line 615  class ArcBase(Manifold1D): Line 640  class ArcBase(Manifold1D):
640         out+=self.getCenterPoint().collectPrimitiveBases()         out+=self.getCenterPoint().collectPrimitiveBases()
641         return out         return out
642    
   
643      def getCenterPoint(self):      def getCenterPoint(self):
644           """           """
645           returns center           Returns the center.
646           """           """
647           raise NotImplementedError()           raise NotImplementedError()
648    
649  class Arc(ArcBase, Primitive):  class Arc(ArcBase, Primitive):
650      """      """
651      defines an arc which is strictly, smaller than Pi      Defines an arc which is strictly smaller than S{pi}.
652      """      """
653      def __init__(self,center,start,end):      def __init__(self,center,start,end):
654         """         """
655         creates an arc by the start point, end point and center         Creates an arc defined by the start point, end point and center.
656         """         """
657         if not isinstance(center,Point): raise TypeError("center needs to be a Point object.")         if not isinstance(center,Point): raise TypeError("center needs to be a Point object.")
658         if not isinstance(end,Point): raise TypeError("end needs to be a Point object.")         if not isinstance(end,Point): raise TypeError("end needs to be a Point object.")
# Line 642  class Arc(ArcBase, Primitive): Line 666  class Arc(ArcBase, Primitive):
666         self.__center=center         self.__center=center
667         self.__start=start         self.__start=start
668         self.__end=end         self.__end=end
669    
670      def __neg__(self):      def __neg__(self):
671            """         """
672            returns a view onto the curve with reversed ordering         Returns a view onto the curve with reversed ordering.
673            """         """
674            return ReverseArc(self)         return ReverseArc(self)
675    
676      def getStartPoint(self):      def getStartPoint(self):
677         """         """
678         returns start point         Returns the start point.
679         """         """
680         return self.__start         return self.__start
681    
682      def getEndPoint(self):      def getEndPoint(self):
683         """         """
684         returns end point         Returns the end point.
685         """         """
686         return self.__end         return self.__end
687    
688      def getCenterPoint(self):      def getCenterPoint(self):
689         """         """
690         returns center         Returns the center point.
691         """         """
692         return self.__center         return self.__center
693    
694      def substitute(self,sub_dict):      def substitute(self,sub_dict):
695          """          """
696          returns a copy of self with substitutes for the primitives used to construct it given by the dictionary C{sub_dict}.          Returns a copy of self with substitutes for the primitives used to
697          If a substitute for the object is given by C{sub_dict} the value is returned, otherwise a new instance          construct it given by the dictionary C{sub_dict}. If a substitute for
698          with substituted arguments is returned.          the object is given by C{sub_dict} the value is returned, otherwise a
699            new instance with substituted arguments is returned.
700          """          """
701          if not sub_dict.has_key(self):          if not sub_dict.has_key(self):
702              sub_dict[self]=Arc(self.getCenterPoint().substitute(sub_dict),self.getStartPoint().substitute(sub_dict),self.getEndPoint().substitute(sub_dict))              sub_dict[self]=Arc(self.getCenterPoint().substitute(sub_dict),self.getStartPoint().substitute(sub_dict),self.getEndPoint().substitute(sub_dict))
703          return sub_dict[self]          return sub_dict[self]
704    
   
705      def isColocated(self,primitive):      def isColocated(self,primitive):
706         """         """
707         returns True curves are on the same position         Returns True if curves are at the same position.
708         """         """
709         if hasattr(primitive,"getUnderlyingPrimitive"):         if hasattr(primitive,"getUnderlyingPrimitive"):
710            if isinstance(primitive.getUnderlyingPrimitive(),Arc):            if isinstance(primitive.getUnderlyingPrimitive(),Arc):
711              return (self.getCenterPoint().isColocated(primitive.getCenterPoint())) and ( \              return (self.getCenterPoint().isColocated(primitive.getCenterPoint())) and ( \
712                     (self.getEndPoint().isColocated(primitive.getEndPoint()) and self.getStartPoint().isColocated(primitive.getStartPoint()) ) \                     (self.getEndPoint().isColocated(primitive.getEndPoint()) and self.getStartPoint().isColocated(primitive.getStartPoint()) ) \
# Line 690  class Arc(ArcBase, Primitive): Line 715  class Arc(ArcBase, Primitive):
715    
716  class ReverseArc(ArcBase, ReversePrimitive):  class ReverseArc(ArcBase, ReversePrimitive):
717      """      """
718      defines an arc which is strictly, smaller than Pi      Defines an arc which is strictly smaller than S{pi}.
719      """      """
720      def __init__(self,arc):      def __init__(self,arc):
721         """         """
722         creates an arc by the start point, end point and center         Creates an arc defined by the start point, end point and center.
723         """         """
724         if not isinstance(arc, Arc):         if not isinstance(arc, Arc):
725             raise TypeError("ReverseCurve needs to be an instance of Arc")             raise TypeError("ReverseCurve needs to be an instance of Arc")
# Line 703  class ReverseArc(ArcBase, ReversePrimiti Line 728  class ReverseArc(ArcBase, ReversePrimiti
728    
729      def getStartPoint(self):      def getStartPoint(self):
730         """         """
731         returns start point         Returns the start point.
732         """         """
733         return self.getUnderlyingPrimitive().getEndPoint()         return self.getUnderlyingPrimitive().getEndPoint()
734    
735      def getEndPoint(self):      def getEndPoint(self):
736         """         """
737         returns end point         Returns the end point.
738         """         """
739         return self.getUnderlyingPrimitive().getStartPoint()         return self.getUnderlyingPrimitive().getStartPoint()
740    
741      def getCenterPoint(self):      def getCenterPoint(self):
742         """         """
743         returns center         Returns the center point.
744         """         """
745         return self.getUnderlyingPrimitive().getCenterPoint()         return self.getUnderlyingPrimitive().getCenterPoint()
746    
747  class EllipseBase(Manifold1D):  class EllipseBase(Manifold1D):
748        """
749        Base class for ellipses.
750        """
751      def __init__(self):      def __init__(self):
752            """         """
753            create ellipse         Initializes the ellipse.
754            """         """
755            Manifold1D.__init__(self)         Manifold1D.__init__(self)
756    
757      def collectPrimitiveBases(self):      def collectPrimitiveBases(self):
758         """         """
759         returns the primitives used to construct the Curve         Returns the primitives used to construct the ellipse.
760         """         """
761         out=[self]         out=[self]
762         out+=self.getStartPoint().collectPrimitiveBases()         out+=self.getStartPoint().collectPrimitiveBases()
# Line 736  class EllipseBase(Manifold1D): Line 765  class EllipseBase(Manifold1D):
765         out+=self.getPointOnMainAxis().collectPrimitiveBases()         out+=self.getPointOnMainAxis().collectPrimitiveBases()
766         return out         return out
767    
   
768  class Ellipse(EllipseBase, Primitive):  class Ellipse(EllipseBase, Primitive):
769      """      """
770      defines an ellipse which is strictly, smaller than Pi      Defines an ellipse which is strictly smaller than S{pi}.
771      """      """
772      def __init__(self,center,point_on_main_axis,start,end):      def __init__(self,center,point_on_main_axis,start,end):
773         """         """
774         creates an arc by the start point, end point, the center and a point on a main axis.         Creates an ellipse defined by the start point, end point, the center
775           and a point on the main axis.
776         """         """
777         if not isinstance(center,Point): raise TypeError("center needs to be a Point object.")         if not isinstance(center,Point): raise TypeError("center needs to be a Point object.")
778         if not isinstance(end,Point): raise TypeError("end needs to be a Point object.")         if not isinstance(end,Point): raise TypeError("end needs to be a Point object.")
# Line 762  class Ellipse(EllipseBase, Primitive): Line 791  class Ellipse(EllipseBase, Primitive):
791         self.__point_on_main_axis=point_on_main_axis         self.__point_on_main_axis=point_on_main_axis
792    
793      def __neg__(self):      def __neg__(self):
794            """         """
795            returns a view onto the curve with reversed ordering         Returns a view onto the curve with reversed ordering.
796            """         """
797            return ReverseEllipse(self)         return ReverseEllipse(self)
798    
799      def getStartPoint(self):      def getStartPoint(self):
800         """         """
801         returns start point         Returns the start point.
802         """         """
803         return self.__start         return self.__start
804    
805      def getEndPoint(self):      def getEndPoint(self):
806         """         """
807         returns end point         Returns the end point.
808         """         """
809         return self.__end         return self.__end
810    
811      def getCenterPoint(self):      def getCenterPoint(self):
812         """         """
813         returns center         Returns the center.
814         """         """
815         return self.__center         return self.__center
816    
817      def getPointOnMainAxis(self):      def getPointOnMainAxis(self):
818         """         """
819         returns a point on a main axis         Returns a point on the main axis.
820         """         """
821         return self.__point_on_main_axis         return self.__point_on_main_axis
822    
823      def substitute(self,sub_dict):      def substitute(self,sub_dict):
824          """          """
825          returns a copy of self with substitutes for the primitives used to construct it given by the dictionary C{sub_dict}.          Returns a copy of self with substitutes for the primitives used to
826          If a substitute for the object is given by C{sub_dict} the value is returned, otherwise a new instance          construct it given by the dictionary C{sub_dict}. If a substitute for
827          with substituted arguments is returned.          the object is given by C{sub_dict} the value is returned, otherwise a
828            new instance with substituted arguments is returned.
829          """          """
830          if not sub_dict.has_key(self):          if not sub_dict.has_key(self):
831              sub_dict[self]=Ellipse(self.getCenterPoint().substitute(sub_dict),              sub_dict[self]=Ellipse(self.getCenterPoint().substitute(sub_dict),
# Line 807  class Ellipse(EllipseBase, Primitive): Line 837  class Ellipse(EllipseBase, Primitive):
837    
838      def isColocated(self,primitive):      def isColocated(self,primitive):
839         """         """
840         returns True curves are on the same position         Returns True if curves are at the same position.
841         """         """
842         if hasattr(primitive,"getUnderlyingPrimitive"):         if hasattr(primitive,"getUnderlyingPrimitive"):
843            if isinstance(primitive.getUnderlyingPrimitive(),Ellipse):            if isinstance(primitive.getUnderlyingPrimitive(),Ellipse):
844              self_c=self.getCenterPoint().getCoordinates()              self_c=self.getCenterPoint().getCoordinates()
845              p=self.getPointOnMainAxis().getCoordinates()-self_c              p=self.getPointOnMainAxis().getCoordinates()-self_c
# Line 819  class Ellipse(EllipseBase, Primitive): Line 849  class Ellipse(EllipseBase, Primitive):
849              len_q=sqrt(q[0]**2+q[1]**2+q[2]**2)              len_q=sqrt(q[0]**2+q[1]**2+q[2]**2)
850              p_q= abs(p[0]*q[0]+p[1]*q[1]+p[2]*q[2])              p_q= abs(p[0]*q[0]+p[1]*q[1]+p[2]*q[2])
851              return ((p_q <= getToleranceForColocation() * len_q * p_q) or \              return ((p_q <= getToleranceForColocation() * len_q * p_q) or \
852                                     (abs(p_q - len_q * p_q) <= getToleranceForColocation())) and \                      (abs(p_q - len_q * p_q) <= getToleranceForColocation())) and \
853                     self.getCenterPoint().isColocated(primitive.getCenterPoint()) and \                     self.getCenterPoint().isColocated(primitive.getCenterPoint()) and \
854                     (                                                                  \                     ( \
855                          (self.getEndPoint().isColocated(primitive.getEndPoint()) and \                      (self.getEndPoint().isColocated(primitive.getEndPoint()) and \
856                           self.getStartPoint().isColocated(primitive.getStartPoint()) ) \                       self.getStartPoint().isColocated(primitive.getStartPoint()) ) \
857                                         or                                              \                      or \
858                           (self.getEndPoint().isColocated(primitive.getStartPoint()) and \                      (self.getEndPoint().isColocated(primitive.getStartPoint()) and \
859                            self.getStartPoint().isColocated(primitive.getEndPoint()) ) \                       self.getStartPoint().isColocated(primitive.getEndPoint())) \
860                     )                     )
861         return False         return False
862    
863  class ReverseEllipse(EllipseBase, ReversePrimitive):  class ReverseEllipse(EllipseBase, ReversePrimitive):
864      """      """
865      defines an arc which is strictly, smaller than Pi      Defines an ellipse which is strictly smaller than S{pi}.
866      """      """
867      def __init__(self,arc):      def __init__(self,arc):
868         """         """
869         creates an instance of a reverse view to an ellipse         Creates an instance of a reverse view to an ellipse.
870         """         """
871         if not isinstance(arc, Ellipse):         if not isinstance(arc, Ellipse):
872             raise TypeError("ReverseCurve needs to be an instance of Ellipse")             raise TypeError("ReverseCurve needs to be an instance of Ellipse")
# Line 845  class ReverseEllipse(EllipseBase, Revers Line 875  class ReverseEllipse(EllipseBase, Revers
875    
876      def getStartPoint(self):      def getStartPoint(self):
877         """         """
878         returns start point         Returns the start point.
879         """         """
880         return self.getUnderlyingPrimitive().getEndPoint()         return self.getUnderlyingPrimitive().getEndPoint()
881    
882      def getEndPoint(self):      def getEndPoint(self):
883         """         """
884         returns end point         Returns the end point.
885         """         """
886         return self.getUnderlyingPrimitive().getStartPoint()         return self.getUnderlyingPrimitive().getStartPoint()
887    
888      def getCenterPoint(self):      def getCenterPoint(self):
889         """         """
890         returns center         Returns the center point.
891         """         """
892         return self.getUnderlyingPrimitive().getCenterPoint()         return self.getUnderlyingPrimitive().getCenterPoint()
893    
894      def getPointOnMainAxis(self):      def getPointOnMainAxis(self):
895         """         """
896         returns a point on a main axis         Returns a point on the main axis.
897         """         """
898         return self.getUnderlyingPrimitive().getPointOnMainAxis()         return self.getUnderlyingPrimitive().getPointOnMainAxis()
899    
900    
901  class CurveLoop(Primitive, PrimitiveBase):  class CurveLoop(Primitive, PrimitiveBase):
902      """      """
903      An oriented loop of one-dimensional manifolds (= curves and arcs)      An oriented loop of one-dimensional manifolds (= curves and arcs).
904    
905      The loop must be closed and the L{Manifold1D}s should be oriented consistently.      The loop must be closed and the L{Manifold1D}s should be oriented
906        consistently.
907      """      """
908      def __init__(self,*curves):      def __init__(self,*curves):
909         """         """
910         creates a polygon from a list of line curves. The curves must form a closed loop.         Creates a polygon from a list of line curves. The curves must form a
911           closed loop.
912         """         """
913         if len(curves)<2:         if len(curves)<2:
914              raise ValueError("at least two curves have to be given.")              raise ValueError("at least two curves have to be given.")
# Line 891  class CurveLoop(Primitive, PrimitiveBase Line 923  class CurveLoop(Primitive, PrimitiveBase
923    
924      def getCurves(self):      def getCurves(self):
925         """         """
926         returns the curves defining the CurveLoop         Returns the curves defining the CurveLoop.
927         """         """
928         return self.__curves         return self.__curves
929    
930      def __neg__(self):      def __neg__(self):
931         """         """
932         returns a view onto the curve with reversed ordering         Returns a view onto the curve with reversed ordering.
933         """         """
934         return ReverseCurveLoop(self)         return ReverseCurveLoop(self)
935    
936      def __len__(self):      def __len__(self):
937         """         """
938         return the number of curves in the CurveLoop         Returns the number of curves in the CurveLoop.
939         """         """
940         return len(self.getCurves())         return len(self.getCurves())
941    
   
942      def collectPrimitiveBases(self):      def collectPrimitiveBases(self):
943         """         """
944         returns primitives used to construct the CurveLoop         Returns primitives used to construct the CurveLoop.
945         """         """
946         out=[self]         out=[self]
947         for c in self.getCurves(): out+=c.collectPrimitiveBases()         for c in self.getCurves(): out+=c.collectPrimitiveBases()
# Line 918  class CurveLoop(Primitive, PrimitiveBase Line 949  class CurveLoop(Primitive, PrimitiveBase
949    
950      def substitute(self,sub_dict):      def substitute(self,sub_dict):
951          """          """
952          returns a copy of self with substitutes for the primitives used to construct it given by the dictionary C{sub_dict}.          Returns a copy of self with substitutes for the primitives used to
953          If a substitute for the object is given by C{sub_dict} the value is returned, otherwise a new instance          construct it given by the dictionary C{sub_dict}. If a substitute for
954          with substituted arguments is returned.          the object is given by C{sub_dict} the value is returned, otherwise a
955            new instance with substituted arguments is returned.
956          """          """
957          if not sub_dict.has_key(self):          if not sub_dict.has_key(self):
958              new_c=[]              new_c=[]
# Line 930  class CurveLoop(Primitive, PrimitiveBase Line 962  class CurveLoop(Primitive, PrimitiveBase
962    
963      def isColocated(self,primitive):      def isColocated(self,primitive):
964         """         """
965         returns True if each curve is colocted with a curve in primitive         Returns True if each curve is colocated with a curve in C{primitive}.
966         """         """
967         if hasattr(primitive,"getUnderlyingPrimitive"):         if hasattr(primitive,"getUnderlyingPrimitive"):
968            if isinstance(primitive.getUnderlyingPrimitive(),CurveLoop):            if isinstance(primitive.getUnderlyingPrimitive(),CurveLoop):
969               if len(primitive) == len(self):               if len(primitive) == len(self):
970                  cp0=self.getCurves()                  cp0=self.getCurves()
971                  cp1=primitive.getCurves()                  cp1=primitive.getCurves()
972                  for c0 in cp0:                  for c0 in cp0:
973                      colocated = False                      colocated = False
974                      for c1 in cp1:                      for c1 in cp1:
975                           colocated = colocated or c0.isColocated(c1)                           colocated = colocated or c0.isColocated(c1)
# Line 947  class CurveLoop(Primitive, PrimitiveBase Line 979  class CurveLoop(Primitive, PrimitiveBase
979    
980  class ReverseCurveLoop(ReversePrimitive, PrimitiveBase):  class ReverseCurveLoop(ReversePrimitive, PrimitiveBase):
981      """      """
982      An oriented loop of one-dimensional manifolds (= curves and arcs)      An oriented loop of one-dimensional manifolds (= curves and arcs).
983    
984      The loop must be closed and the one-dimensional manifolds should be oriented consistently.      The loop must be closed and the one-dimensional manifolds should be
985        oriented consistently.
986      """      """
987      def __init__(self,curve_loop):      def __init__(self,curve_loop):
988         """         """
989         creates a polygon from a list of line curves. The curves must form a closed loop.         Creates a polygon from a list of line curves. The curves must form a
990           closed loop.
991         """         """
992         if not isinstance(curve_loop, CurveLoop):         if not isinstance(curve_loop, CurveLoop):
993             raise TypeError("arguments need to be an instance of CurveLoop.")             raise TypeError("arguments need to be an instance of CurveLoop.")
# Line 962  class ReverseCurveLoop(ReversePrimitive, Line 996  class ReverseCurveLoop(ReversePrimitive,
996    
997      def getCurves(self):      def getCurves(self):
998         """         """
999         returns the curves defining the CurveLoop         Returns the curves defining the CurveLoop.
1000         """         """
1001         return [ -c for c in  self.getUnderlyingPrimitive().getCurves() ]         return [ -c for c in  self.getUnderlyingPrimitive().getCurves() ]
1002    
# Line 972  class ReverseCurveLoop(ReversePrimitive, Line 1006  class ReverseCurveLoop(ReversePrimitive,
1006  #=  #=
1007  class Manifold2D(PrimitiveBase):  class Manifold2D(PrimitiveBase):
1008      """      """
1009      general two-dimensional manifold      General two-dimensional manifold.
1010      """      """
1011      def __init__(self):      def __init__(self):
1012         """         """
1013         create a two-dimensional manifold         Creates a two-dimensional manifold.
1014         """         """
1015         PrimitiveBase.__init__(self)         PrimitiveBase.__init__(self)
1016    
1017      def getBoundary(self):      def getBoundary(self):
1018          """          """
1019          returns a list of the one-dimensional manifolds forming the boundary of the Surface (including holes)          Returns a list of the one-dimensional manifolds forming the boundary
1020            of the surface (including holes).
1021          """          """
1022          raise NotImplementedError()          raise NotImplementedError()
1023    
1024  class RuledSurface(Primitive, Manifold2D):  class RuledSurface(Primitive, Manifold2D):
1025      """      """
1026      A ruled surface, i.e., a surface that can be interpolated using transfinite interpolation      A ruled surface, i.e. a surface that can be interpolated using transfinite
1027        interpolation.
1028      """      """
1029      def __init__(self,loop):      def __init__(self,loop):
1030         """         """
1031         creates a ruled surface with boundary loop         Creates a ruled surface with boundary C{loop}.
1032    
1033         @param loop: L{CurveLoop} defining the boundary of the surface.         @param loop: L{CurveLoop} defining the boundary of the surface.
1034         """         """
1035         if not isinstance(loop.getUnderlyingPrimitive(),CurveLoop):         if not isinstance(loop.getUnderlyingPrimitive(),CurveLoop):
1036             raise TypeError("argument loop needs to be a CurveLoop object.")             raise TypeError("argument loop needs to be a CurveLoop object.")
1037         if len(loop)<2:         if len(loop)<2:
1038             raise ValueError("the loop must contain at least two Curves.")             raise ValueError("the loop must contain at least two Curves.")
1039         if len(loop)>4:         if len(loop)>4:
1040             raise ValueError("the loop must contain at least three Curves.")             raise ValueError("the loop must contain at most four Curves.")
1041         Primitive.__init__(self)         Primitive.__init__(self)
1042         Manifold2D.__init__(self)         Manifold2D.__init__(self)
1043         self.__loop=loop         self.__loop=loop
1044    
1045      def __neg__(self):      def __neg__(self):
1046            """          """
1047            returns a view onto the suface with reversed ordering          Returns a view onto the suface with reversed ordering.
1048            """          """
1049            return ReverseRuledSurface(self)          return ReverseRuledSurface(self)
1050    
1051      def getBoundaryLoop(self):      def getBoundaryLoop(self):
1052          """          """
1053          returns the loop defining the outer boundary          Returns the loop defining the outer boundary.
1054          """          """
1055          return self.__loop          return self.__loop
1056    
1057      def getBoundary(self):      def getBoundary(self):
1058          """          """
1059          returns a list of the one-dimensional manifolds forming the boundary of the Surface (including holes)          Returns a list of the one-dimensional manifolds forming the boundary
1060            of the Surface (including holes).
1061          """          """
1062          return self.getBoundaryLoop().getCurves()          return self.getBoundaryLoop().getCurves()
1063    
1064      def substitute(self,sub_dict):      def substitute(self,sub_dict):
1065          """          """
1066          returns a copy of self with substitutes for the primitives used to construct it given by the dictionary C{sub_dict}.          Returns a copy of self with substitutes for the primitives used to
1067          If a substitute for the object is given by C{sub_dict} the value is returned, otherwise a new instance          construct it given by the dictionary C{sub_dict}. If a substitute for
1068          with substituted arguments is returned.          the object is given by C{sub_dict} the value is returned, otherwise a
1069            new instance with substituted arguments is returned.
1070          """          """
1071          if not sub_dict.has_key(self):          if not sub_dict.has_key(self):
1072              sub_dict[self]=RuledSurface(self.getBoundaryLoop().substitute(sub_dict))              sub_dict[self]=RuledSurface(self.getBoundaryLoop().substitute(sub_dict))
# Line 1036  class RuledSurface(Primitive, Manifold2D Line 1074  class RuledSurface(Primitive, Manifold2D
1074    
1075      def isColocated(self,primitive):      def isColocated(self,primitive):
1076         """         """
1077         returns True if each curve is colocted with a curve in primitive         Returns True if each curve is colocated with a curve in C{primitive}.
1078         """         """
1079         if hasattr(primitive,"getUnderlyingPrimitive"):         if hasattr(primitive,"getUnderlyingPrimitive"):
1080            if isinstance(primitive.getUnderlyingPrimitive(),RuledSurface):            if isinstance(primitive.getUnderlyingPrimitive(),RuledSurface):
1081               return self.getBoundaryLoop().isColocated(primitive.getBoundaryLoop())               return self.getBoundaryLoop().isColocated(primitive.getBoundaryLoop())
1082         return False         return False
1083    
1084      def collectPrimitiveBases(self):      def collectPrimitiveBases(self):
1085          """          """
1086          returns primitives used to construct the Surface          Returns primitives used to construct the Surface.
1087          """          """
1088          return [self] + self.getBoundaryLoop().collectPrimitiveBases()          return [self] + self.getBoundaryLoop().collectPrimitiveBases()
1089    
1090  def createRuledSurface(*curves):  def createRuledSurface(*curves):
1091        """        """
1092        an easier way to create a L{RuledSurface} from given curves.        An easier way to create a L{RuledSurface} from given curves.
1093        """        """
1094        return RuledSurface(CurveLoop(*curves))        return RuledSurface(CurveLoop(*curves))
1095    
1096    
1097  class ReverseRuledSurface(ReversePrimitive, Manifold2D):  class ReverseRuledSurface(ReversePrimitive, Manifold2D):
1098      """      """
1099      creates a view onto a L{RuledSurface} but with the reverse orientation      Creates a view onto a L{RuledSurface} but with reverse orientation.
1100      """      """
1101      def __init__(self,surface):      def __init__(self,surface):
1102         """         """
1103         creates a polygon from a list of line curves. The curves must form a closed loop.         Creates a polygon from a list of line curves. The curves must form a
1104           closed loop.
1105         """         """
1106         if not isinstance(surface, RuledSurface):         if not isinstance(surface, RuledSurface):
1107             raise TypeError("arguments need to be an instance of CurveLoop.")             raise TypeError("arguments need to be an instance of CurveLoop.")
# Line 1071  class ReverseRuledSurface(ReversePrimiti Line 1110  class ReverseRuledSurface(ReversePrimiti
1110    
1111      def getBoundaryLoop(self):      def getBoundaryLoop(self):
1112         """         """
1113         returns the CurveLoop defining the RuledSurface         Returns the CurveLoop defining the ReverseRuledSurface.
1114         """         """
1115         return -self.getUnderlyingPrimitive().getBoundaryLoop()         return -self.getUnderlyingPrimitive().getBoundaryLoop()
1116    
1117      def getBoundary(self):      def getBoundary(self):
1118          """         """
1119          returns a list of the one-dimensional manifolds forming the boundary of the Surface (including holes)         Returns a list of the one-dimensional manifolds forming the boundary
1120          """         of the Surface (including holes).
1121          return self.getBoundaryLoop().getCurves()         """
1122           return self.getBoundaryLoop().getCurves()
1123    
1124  #==============================  #==============================
1125  class PlaneSurface(Primitive, Manifold2D):  class PlaneSurface(Primitive, Manifold2D):
1126      """      """
1127      a plane surface with holes      A plane surface with holes.
1128      """      """
1129      def __init__(self,loop,holes=[]):      def __init__(self,loop,holes=[]):
1130         """         """
1131         creates a  plane surface with a hole         Creates a plane surface with holes.
1132    
1133         @param loop: L{CurveLoop} defining the boundary of the surface         @param loop: L{CurveLoop} defining the boundary of the surface
1134         @param holes: list of L{CurveLoop} defining holes in the surface.         @param holes: list of L{CurveLoop}s defining holes in the surface
1135         @note: A CurveLoop defining a hole should not have any lines in common with the exterior CurveLoop.           @note: A CurveLoop defining a hole should not have any lines in common
1136                A CurveLoop defining a hole should not have any lines in common with another CurveLoop defining a hole in the same surface.                with the exterior CurveLoop.
1137           @note: A CurveLoop defining a hole should not have any lines in common
1138                  with another CurveLoop defining a hole in the same surface.
1139         """         """
1140         if not isinstance(loop.getUnderlyingPrimitive(),CurveLoop):         if not isinstance(loop.getUnderlyingPrimitive(),CurveLoop):
1141             raise TypeError("argument loop needs to be a CurveLoop object.")             raise TypeError("argument loop needs to be a CurveLoop object.")
# Line 1105  class PlaneSurface(Primitive, Manifold2D Line 1148  class PlaneSurface(Primitive, Manifold2D
1148         Manifold2D.__init__(self)         Manifold2D.__init__(self)
1149         self.__loop=loop         self.__loop=loop
1150         self.__holes=holes         self.__holes=holes
1151    
1152      def getHoles(self):      def getHoles(self):
1153         """         """
1154         returns the holes         Returns the holes.
1155         """         """
1156         return self.__holes         return self.__holes
1157    
1158      def getBoundaryLoop(self):      def getBoundaryLoop(self):
1159          """          """
1160          returns the loop defining the boundary          Returns the loop defining the boundary.
1161          """          """
1162          return self.__loop          return self.__loop
1163    
1164      def substitute(self,sub_dict):      def substitute(self,sub_dict):
1165          """          """
1166          returns a copy of self with substitutes for the primitives used to construct it given by the dictionary C{sub_dict}.          Returns a copy of self with substitutes for the primitives used to
1167          If a substitute for the object is given by C{sub_dict} the value is returned, otherwise a new instance          construct it given by the dictionary C{sub_dict}. If a substitute for
1168          with substituted arguments is returned.          the object is given by C{sub_dict} the value is returned, otherwise a
1169            new instance with substituted arguments is returned.
1170          """          """
1171          if not sub_dict.has_key(self):          if not sub_dict.has_key(self):
1172              sub_dict[self]=PlaneSurface(self.getBoundaryLoop().substitute(sub_dict),[ h.substitute(sub_dict) for h in self.getHoles()])              sub_dict[self]=PlaneSurface(self.getBoundaryLoop().substitute(sub_dict),[ h.substitute(sub_dict) for h in self.getHoles()])
# Line 1129  class PlaneSurface(Primitive, Manifold2D Line 1174  class PlaneSurface(Primitive, Manifold2D
1174    
1175      def isColocated(self,primitive):      def isColocated(self,primitive):
1176         """         """
1177         returns True if each curve is colocted with a curve in primitive         Returns True if each curve is colocated with a curve in C{primitive}.
1178         """         """
1179         if hasattr(primitive,"getUnderlyingPrimitive"):         if hasattr(primitive,"getUnderlyingPrimitive"):
1180            if isinstance(primitive.getUnderlyingPrimitive(),PlaneSurface):            if isinstance(primitive.getUnderlyingPrimitive(),PlaneSurface):
1181               if self.getBoundaryLoop().isColocated(primitive.getBoundaryLoop()):               if self.getBoundaryLoop().isColocated(primitive.getBoundaryLoop()):
1182                  hs0=self.getHoles()                  hs0=self.getHoles()
# Line 1139  class PlaneSurface(Primitive, Manifold2D Line 1184  class PlaneSurface(Primitive, Manifold2D
1184                  if len(hs0) == len(hs1):                  if len(hs0) == len(hs1):
1185                      for h0 in hs0:                      for h0 in hs0:
1186                         colocated = False                         colocated = False
1187                         for h1 in hs1:                         for h1 in hs1:
1188                           colocated = colocated or h0.isColocated(h1)                           colocated = colocated or h0.isColocated(h1)
1189                         if not colocated: return False                         if not colocated: return False
1190                      return True                      return True
1191         return False         return False
1192    
1193      def collectPrimitiveBases(self):      def collectPrimitiveBases(self):
1194          """          """
1195          returns primitives used to construct the Surface          Returns primitives used to construct the Surface.
1196          """          """
1197          out=[self] + self.getBoundaryLoop().collectPrimitiveBases()          out=[self] + self.getBoundaryLoop().collectPrimitiveBases()
1198          for i in self.getHoles(): out+=i.collectPrimitiveBases()          for i in self.getHoles(): out+=i.collectPrimitiveBases()
1199          return out          return out
1200    
1201      def __neg__(self):      def __neg__(self):
1202            """          """
1203            returns a view onto the curve with reversed ordering          Returns a view onto the curve with reversed ordering.
1204            """          """
1205            return ReversePlaneSurface(self)          return ReversePlaneSurface(self)
1206    
1207      def getBoundary(self):      def getBoundary(self):
1208          """          """
1209          returns a list of the one-dimensional manifolds forming the boundary of the Surface (including holes)          Returns a list of the one-dimensional manifolds forming the boundary
1210            of the Surface (including holes).
1211          """          """
1212          out = []+ self.getBoundaryLoop().getCurves()          out = []+ self.getBoundaryLoop().getCurves()
1213          for h in self.getHoles(): out+=h.getCurves()          for h in self.getHoles(): out+=h.getCurves()
# Line 1166  class PlaneSurface(Primitive, Manifold2D Line 1215  class PlaneSurface(Primitive, Manifold2D
1215    
1216  class ReversePlaneSurface(ReversePrimitive, Manifold2D):  class ReversePlaneSurface(ReversePrimitive, Manifold2D):
1217      """      """
1218      creates a view onto a L{PlaneSurface} but with the reverse orientation      Creates a view onto a L{PlaneSurface} but with reverse orientation.
1219      """      """
1220      def __init__(self,surface):      def __init__(self,surface):
1221         """         """
1222         creates a polygon from a list of line curves. The curves must form a closed loop.         Creates a polygon from a L{PlaneSurface}.
1223         """         """
1224         if not isinstance(surface, PlaneSurface):         if not isinstance(surface, PlaneSurface):
1225             raise TypeError("arguments need to be an instance of PlaneSurface.")             raise TypeError("arguments need to be an instance of PlaneSurface.")
# Line 1179  class ReversePlaneSurface(ReversePrimiti Line 1228  class ReversePlaneSurface(ReversePrimiti
1228    
1229      def getBoundaryLoop(self):      def getBoundaryLoop(self):
1230         """         """
1231         returns the CurveLoop defining the RuledSurface         Returns the CurveLoop defining the ReversePlaneSurface.
1232         """         """
1233         return -self.getUnderlyingPrimitive().getBoundaryLoop()         return -self.getUnderlyingPrimitive().getBoundaryLoop()
1234    
1235      def getHoles(self):      def getHoles(self):
1236          """          """
1237          returns a list of the one-dimensional manifolds forming the boundary of the Surface (including holes)          Returns the holes.
1238          """          """
1239          return [ -h for h in self.getUnderlyingPrimitive().getHoles() ]          return [ -h for h in self.getUnderlyingPrimitive().getHoles() ]
1240    
1241      def getBoundary(self):      def getBoundary(self):
1242          """          """
1243          returns a list of the one-dimensional manifolds forming the boundary of the Surface (including holes)          Returns a list of the one-dimensional manifolds forming the boundary
1244            of the Surface (including holes).
1245          """          """
1246          out = [] + self.getBoundaryLoop().getCurves()          out = [] + self.getBoundaryLoop().getCurves()
1247          for h in self.getHoles(): out+=h.getCurves()          for h in self.getHoles(): out+=h.getCurves()
# Line 1201  class ReversePlaneSurface(ReversePrimiti Line 1251  class ReversePlaneSurface(ReversePrimiti
1251  #=========================================================================  #=========================================================================
1252  class SurfaceLoop(Primitive, PrimitiveBase):  class SurfaceLoop(Primitive, PrimitiveBase):
1253      """      """
1254      a loop of 2D primitives. It defines the shell of a volume.      A loop of 2D primitives which defines the shell of a volume.
1255    
1256      The loop must represent a closed shell, and the primitives should be oriented consistently.      The loop must represent a closed shell, and the primitives should be
1257        oriented consistently.
1258      """      """
1259      def __init__(self,*surfaces):      def __init__(self,*surfaces):
1260         """         """
1261         creates a surface loop         Creates a surface loop.
1262         """         """
1263         if len(surfaces)<2:         if len(surfaces)<2:
1264              raise ValueError("at least two surfaces have to be given.")              raise ValueError("at least two surfaces have to be given.")
# Line 1217  class SurfaceLoop(Primitive, PrimitiveBa Line 1268  class SurfaceLoop(Primitive, PrimitiveBa
1268         self.__surfaces=list(surfaces)         self.__surfaces=list(surfaces)
1269         Primitive.__init__(self)         Primitive.__init__(self)
1270         PrimitiveBase.__init__(self)         PrimitiveBase.__init__(self)
1271    
1272      def __len__(self):      def __len__(self):
1273         """         """
1274         return the number of curves in the SurfaceLoop         Returns the number of curves in the SurfaceLoop.
1275         """         """
1276         return len(self.__surfaces)         return len(self.__surfaces)
1277    
1278      def __neg__(self):      def __neg__(self):
1279         """         """
1280         returns a view onto the curve with reversed ordering         Returns a view onto the curve with reversed ordering.
1281         """         """
1282         return ReverseSurfaceLoop(self)         return ReverseSurfaceLoop(self)
1283    
1284      def getSurfaces(self):      def getSurfaces(self):
1285         """         """
1286         returns the surfaces defining the SurfaceLoop         Returns the surfaces defining the SurfaceLoop.
1287         """         """
1288         return self.__surfaces         return self.__surfaces
1289    
1290      def collectPrimitiveBases(self):      def collectPrimitiveBases(self):
1291         """         """
1292         returns primitives used to construct the SurfaceLoop         Returns primitives used to construct the SurfaceLoop.
1293         """         """
1294         out=[self]         out=[self]
1295         for c in self.getSurfaces(): out+=c.collectPrimitiveBases()         for c in self.getSurfaces(): out+=c.collectPrimitiveBases()
# Line 1245  class SurfaceLoop(Primitive, PrimitiveBa Line 1297  class SurfaceLoop(Primitive, PrimitiveBa
1297    
1298      def substitute(self,sub_dict):      def substitute(self,sub_dict):
1299          """          """
1300          returns a copy of self with substitutes for the primitives used to construct it given by the dictionary C{sub_dict}.          Returns a copy of self with substitutes for the primitives used to
1301          If a substitute for the object is given by C{sub_dict} the value is returned, otherwise a new instance          construct it given by the dictionary C{sub_dict}. If a substitute for
1302          with substituted arguments is returned.          the object is given by C{sub_dict} the value is returned, otherwise a
1303            new instance with substituted arguments is returned.
1304          """          """
1305          if not sub_dict.has_key(self):          if not sub_dict.has_key(self):
1306              new_s=[]              new_s=[]
# Line 1257  class SurfaceLoop(Primitive, PrimitiveBa Line 1310  class SurfaceLoop(Primitive, PrimitiveBa
1310    
1311      def isColocated(self,primitive):      def isColocated(self,primitive):
1312         """         """
1313         returns True if each surface is colocted with a curve in primitive and vice versa.         Returns True if each surface is colocated with a curve in C{primitive}
1314           and vice versa.
1315         """         """
1316         if hasattr(primitive,"getUnderlyingPrimitive"):         if hasattr(primitive,"getUnderlyingPrimitive"):
1317           if isinstance(primitive.getUnderlyingPrimitive(),SurfaceLoop):           if isinstance(primitive.getUnderlyingPrimitive(),SurfaceLoop):
1318              if len(primitive) == len(self):              if len(primitive) == len(self):
1319                  sp0=self.getSurfaces()                  sp0=self.getSurfaces()
1320                  sp1=primitive.getSurfaces()                  sp1=primitive.getSurfaces()
1321                  for s0 in sp0:                  for s0 in sp0:
1322                      colocated = False                      colocated = False
1323                      for s1 in sp1:                      for s1 in sp1:
1324                           colocated = colocated or s0.isColocated(s1)                           colocated = colocated or s0.isColocated(s1)
# Line 1274  class SurfaceLoop(Primitive, PrimitiveBa Line 1328  class SurfaceLoop(Primitive, PrimitiveBa
1328    
1329  class ReverseSurfaceLoop(ReversePrimitive, PrimitiveBase):  class ReverseSurfaceLoop(ReversePrimitive, PrimitiveBase):
1330      """      """
1331      a view to SurfaceLoop with reverse orientaion      A view of a SurfaceLoop with reverse orientation.
1332    
1333      The loop must represent a closed shell, and the primitives should be oriented consistently.      The loop must represent a closed shell and the primitives should be
1334      An oriented loop of 2-dimensional manifolds (= RuledSurface, PlaneSurface)      oriented consistently.
   
     The loop must be closed and the one-dimensional manifolds should be oriented consistently.  
1335      """      """
1336      def __init__(self,surface_loop):      def __init__(self,surface_loop):
1337         """         """
1338         creates a polygon from a list of line surfaces. The curves must form a closed loop.         Creates a polygon from a list of line surfaces. The curves must form
1339           a closed loop.
1340         """         """
1341         if not isinstance(surface_loop, SurfaceLoop):         if not isinstance(surface_loop, SurfaceLoop):
1342             raise TypeError("arguments need to be an instance of SurfaceLoop.")             raise TypeError("arguments need to be an instance of SurfaceLoop.")
# Line 1292  class ReverseSurfaceLoop(ReversePrimitiv Line 1345  class ReverseSurfaceLoop(ReversePrimitiv
1345    
1346      def getSurfaces(self):      def getSurfaces(self):
1347         """         """
1348         returns the surfaces defining the SurfaceLoop         Returns the surfaces defining the SurfaceLoop.
1349         """         """
1350         return [ -s for s in  self.getUnderlyingPrimitive().getSurfaces() ]         return [ -s for s in  self.getUnderlyingPrimitive().getSurfaces() ]
1351    
# Line 1302  class ReverseSurfaceLoop(ReversePrimitiv Line 1355  class ReverseSurfaceLoop(ReversePrimitiv
1355  #==============================  #==============================
1356  class Manifold3D(PrimitiveBase):  class Manifold3D(PrimitiveBase):
1357      """      """
1358      general three-dimensional manifold      General three-dimensional manifold.
1359      """      """
1360      def __init__(self):      def __init__(self):
1361         """         """
1362         create a three-dimensional manifold         Creates a three-dimensional manifold.
1363         """         """
1364         PrimitiveBase.__init__(self)         PrimitiveBase.__init__(self)
1365    
1366      def getBoundary(self):      def getBoundary(self):
1367          """          """
1368          returns a list of the one-dimensional manifolds forming the boundary of the volume (including holes)          Returns a list of the one-dimensional manifolds forming the boundary
1369            of the volume (including holes).
1370          """          """
1371          raise NotImplementedError()          raise NotImplementedError()
1372    
1373  class Volume(Manifold3D, Primitive):  class Volume(Manifold3D, Primitive):
1374      """      """
1375      a volume with holes.      A volume with holes.
1376      """      """
1377      def __init__(self,loop,holes=[]):      def __init__(self,loop,holes=[]):
1378         """         """
1379         creates a volume         Creates a volume with holes.
1380    
1381         @param loop: L{SurfaceLoop} defining the boundary of the surface         @param loop: L{SurfaceLoop} defining the boundary of the surface
1382         @param holes: list of L{SurfaceLoop} defining holes in the surface.         @param holes: list of L{SurfaceLoop} defining holes in the surface
1383         @note: A SurfaceLoop defining a hole should not have any surfaces in common with the exterior SurfaceLoop.           @note: A SurfaceLoop defining a hole should not have any surfaces in
1384                A SurfaceLoop defining a hole should not have any surfaces in common with another SurfaceLoop defining a hole in the same volume.                common with the exterior SurfaceLoop.
1385           @note: A SurfaceLoop defining a hole should not have any surfaces in
1386                  common with another SurfaceLoop defining a hole in the same
1387                  volume.
1388         """         """
1389         if not isinstance(loop.getUnderlyingPrimitive(), SurfaceLoop):         if not isinstance(loop.getUnderlyingPrimitive(), SurfaceLoop):
1390             raise TypeError("argument loop needs to be a SurfaceLoop object.")             raise TypeError("argument loop needs to be a SurfaceLoop object.")
# Line 1338  class Volume(Manifold3D, Primitive): Line 1395  class Volume(Manifold3D, Primitive):
1395         Manifold3D.__init__(self)         Manifold3D.__init__(self)
1396         self.__loop=loop         self.__loop=loop
1397         self.__holes=holes         self.__holes=holes
1398    
1399      def getHoles(self):      def getHoles(self):
1400         """         """
1401         returns the hole in the volume         Returns the holes in the volume.
1402         """         """
1403         return self.__holes         return self.__holes
1404    
1405      def getSurfaceLoop(self):      def getSurfaceLoop(self):
1406         """         """
1407         returns the loop forming the surface         Returns the loop forming the surface.
1408         """         """
1409         return self.__loop         return self.__loop
1410    
1411      def substitute(self,sub_dict):      def substitute(self,sub_dict):
1412          """          """
1413          returns a copy of self with substitutes for the primitives used to construct it given by the dictionary C{sub_dict}.          Returns a copy of self with substitutes for the primitives used to
1414          If a substitute for the object is given by C{sub_dict} the value is returned, otherwise a new instance          construct it given by the dictionary C{sub_dict}. If a substitute for
1415          with substituted arguments is returned.          the object is given by C{sub_dict} the value is returned, otherwise a
1416            new instance with substituted arguments is returned.
1417          """          """
1418          if not sub_dict.has_key(self):          if not sub_dict.has_key(self):
1419              sub_dict[self]=Volume(self.getSurfaceLoop().substitute(sub_dict),[ h.substitute(sub_dict) for h in self.getHoles()])              sub_dict[self]=Volume(self.getSurfaceLoop().substitute(sub_dict),[ h.substitute(sub_dict) for h in self.getHoles()])
# Line 1361  class Volume(Manifold3D, Primitive): Line 1421  class Volume(Manifold3D, Primitive):
1421    
1422      def isColocated(self,primitive):      def isColocated(self,primitive):
1423         """         """
1424         returns True if each curve is colocted with a curve in primitive         Returns True if each curve is colocated with a curve in C{primitive}.
1425         """         """
1426         if hasattr(primitive,"getUnderlyingPrimitive"):         if hasattr(primitive,"getUnderlyingPrimitive"):
1427            if isinstance(primitive.getUnderlyingPrimitive(),Volume):            if isinstance(primitive.getUnderlyingPrimitive(),Volume):
1428               if self.getSurfaceLoop().isColocated(primitive.getSurfaceLoop()):               if self.getSurfaceLoop().isColocated(primitive.getSurfaceLoop()):
1429                  hs0=self.getHoles()                  hs0=self.getHoles()
# Line 1371  class Volume(Manifold3D, Primitive): Line 1431  class Volume(Manifold3D, Primitive):
1431                  if len(hs0) == len(hs1):                  if len(hs0) == len(hs1):
1432                      for h0 in hs0:                      for h0 in hs0:
1433                         colocated = False                         colocated = False
1434                         for h1 in hs1:                         for h1 in hs1:
1435                           colocated = colocated or h0.isColocated(h1)                           colocated = colocated or h0.isColocated(h1)
1436                         if not colocated: return False                         if not colocated: return False
1437                      return True                      return True
1438         return False         return False
1439    
1440      def collectPrimitiveBases(self):      def collectPrimitiveBases(self):
1441          """          """
1442          returns primitives used to construct the Surface          Returns primitives used to construct the surface.
1443          """          """
1444          out=[self] + self.getSurfaceLoop().collectPrimitiveBases()          out=[self] + self.getSurfaceLoop().collectPrimitiveBases()
1445          for i in self.getHoles(): out+=i.collectPrimitiveBases()          for i in self.getHoles(): out+=i.collectPrimitiveBases()
1446          return out          return out
1447    
1448      def getBoundary(self):      def getBoundary(self):
1449          """          """
1450          returns a list of the one-dimensional manifolds forming the boundary of the Surface (including holes)          Returns a list of the one-dimensional manifolds forming the boundary
1451            of the Surface (including holes).
1452          """          """
1453          out = []+ self.getSurfaceLoop().getSurfaces()          out = []+ self.getSurfaceLoop().getSurfaces()
1454          for h in self.getHoles(): out+=h.getSurfaces()          for h in self.getHoles(): out+=h.getSurfaces()
# Line 1393  class Volume(Manifold3D, Primitive): Line 1456  class Volume(Manifold3D, Primitive):
1456    
1457  class PropertySet(Primitive, PrimitiveBase):  class PropertySet(Primitive, PrimitiveBase):
1458      """      """
1459      defines a group of L{Primitive} which can be accessed through a name      Defines a group of L{Primitive}s which can be accessed through a name.
1460      """      """
1461      def __init__(self,name,*items):      def __init__(self,name,*items):
1462         Primitive.__init__(self)         Primitive.__init__(self)
# Line 1404  class PropertySet(Primitive, PrimitiveBa Line 1467  class PropertySet(Primitive, PrimitiveBa
1467    
1468      def getDim(self):      def getDim(self):
1469         """         """
1470         returns the dimension of the items         Returns the dimensionality of the items.
1471         """         """
1472         if self.__dim == None:         if self.__dim == None:
1473             items=self.getItems()             items=self.getItems()
1474             if len(items)>0:             if len(items)>0:
1475                  if isinstance(items[0] ,Manifold1D):                  if isinstance(items[0] ,Manifold1D):
1476                       self.__dim=1                       self.__dim=1
1477                  elif isinstance(items[0] ,Manifold2D):                  elif isinstance(items[0] ,Manifold2D):
1478                       self.__dim=2                       self.__dim=2
1479                  elif isinstance(items[0] ,Manifold3D):                  elif isinstance(items[0] ,Manifold3D):
1480                      self.__dim=3                      self.__dim=3
1481                  else:                  else:
1482                      self.__dim=0                      self.__dim=0
1483         return self.__dim         return self.__dim
1484    
1485      def __repr__(self):      def __repr__(self):
1486         """         """
1487         returns a string representation         Returns a string representation.
1488         """         """
1489         return "%s(%s)"%(self.getName(),self.getID())         return "%s(%s)"%(self.getName(),self.getID())
1490    
1491      def getManifoldClass(self):      def getManifoldClass(self):
1492          """          """
1493          returns the manifold class expected from items          Returns the manifold class expected from items.
1494          """          """
1495          d=self.getDim()          d=self.getDim()
1496          if d == None:          if d == None:
# Line 1442  class PropertySet(Primitive, PrimitiveBa Line 1507  class PropertySet(Primitive, PrimitiveBa
1507    
1508      def getName(self):      def getName(self):
1509          """          """
1510          returns the name of the set          Returns the name of the set.
1511          """          """
1512          return self.__name          return self.__name
1513    
1514      def setName(self,name):      def setName(self,name):
1515          """          """
1516          sets the name.          Sets the name.
1517          """          """
1518          self.__name=str(name)          self.__name=str(name)
1519    
1520      def addItems(self,*items):      def addItems(self,*items):
1521          """          """
1522          adds items. An item my be any L{Primitive} but no L{PropertySet}          Adds items. An item my be any L{Primitive} but no L{PropertySet}.
1523          """          """
1524          self.addItem(*items)          self.addItem(*items)
1525    
1526      def addItem(self,*items):      def addItem(self,*items):
1527          """          """
1528          adds items. An item my be any L{Primitive} but no L{PropertySet}          Adds items. An item my be any L{Primitive} but no L{PropertySet}.
1529          """          """
1530          for i in items:          for i in items:
1531              if not i in self.__items:              if not i in self.__items:
1532                 if len(self.__items)>0:                 if len(self.__items)>0:
1533                    m=self.getManifoldClass()                    m=self.getManifoldClass()
1534                    if not isinstance(i, m):                    if not isinstance(i, m):
1535                       raise TypeError("argument %s is not a %s class object."%(i, m.__name__))                       raise TypeError("argument %s is not a %s class object."%(i, m.__name__))
1536                 self.__items.append(i)                 self.__items.append(i)
1537    
1538      def getNumItems(self):      def getNumItems(self):
1539          """          """
1540          returns the number of items in the property set          Returns the number of items in the property set.
1541          """          """
1542          return len(self.__items)          return len(self.__items)
1543    
1544      def getItems(self):      def getItems(self):
1545          """          """
1546          returns the list of items          Returns the list of items.
1547          """          """
1548          return self.__items          return self.__items
1549    
1550      def clearItems(self):      def clearItems(self):
1551          """          """
1552          clears the list of items          Clears the list of items.
1553          """          """
1554          self.__items=[]          self.__items=[]
1555    
1556      def collectPrimitiveBases(self):      def collectPrimitiveBases(self):
1557          """          """
1558          returns primitives used to construct the PropertySet          Returns primitives used to construct the PropertySet.
1559          """          """
1560          out=[self]          out=[self]
1561          for i in self.getItems(): out+=i.collectPrimitiveBases()          for i in self.getItems(): out+=i.collectPrimitiveBases()
1562          return out          return out
1563    
1564      def getTag(self):      def getTag(self):
1565           """          """
1566           returns the tag used for this property set          Returns the tag used for this property set.
1567           """          """
1568           return self.getID()          return self.getID()
1569    

Legend:
Removed from v.2213  
changed lines
  Added in v.2214

  ViewVC Help
Powered by ViewVC 1.1.26