/[escript]/trunk/pycad/py_src/primitives.py
ViewVC logotype

Diff of /trunk/pycad/py_src/primitives.py

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

trunk/pycad/py_src/elementries.py revision 898 by gross, Sun Nov 12 23:56:26 2006 UTC trunk/pycad/py_src/primitives.py revision 899 by gross, Mon Nov 13 08:02:24 2006 UTC
# Line 1  Line 1 
1  # $Id:$  # $Id:$
2    
3  """  """
4  Geometrical Elementries  Geometrical Primitives
5    
6  the concept is inspired by gmsh and very much focused on the fact that  the concept is inspired by gmsh and very much focused on the fact that
7  the classes are used to wrk with gmsh.  the classes are used to wrk with gmsh.
# Line 25  __url__="http://www.iservo.edu.au/esys/e Line 25  __url__="http://www.iservo.edu.au/esys/e
25  __version__="$Revision:$"  __version__="$Revision:$"
26  __date__="$Date:$"  __date__="$Date:$"
27    
28  class Elementary(object):  import numarray
29    
30    global global_primitive_id_counter
31    global_primitive_id_counter=0
32    
33    class Primitive(object):
34      """      """
35      template for elementary geometrical object      template for elementary geometrical object
36      """      """
37      def __init__(self):      def __init__(self):
38         """         """
39         """         """
40         pass         global global_primitive_id_counter
41           self.__ID=global_primitive_id_counter
42           global_primitive_id_counter+=1
43        def getID(self):
44           return self.__ID
45        def __repr__(self):
46           return "%s(%s)"%(self.__class__.__name__,self.getID())
47        def __cmp__(self,other):
48           return cmp(self.getID(),other.getID())
49        def getGmshCommand(self):
50            raise NotImplementedError("getGmshCommand is not implemented for this class %s."%self.__class__.__name__)
51        def isPoint(self):
52            return False
53        def isCurve(self):
54            return False
55        def isSurface(self):
56            return False
57        def isCurveLoop(self):
58            return False
59        def isSurfaceLoop(self):
60            return False
61        def __neg__(self):
62            return ReversedPrimitive(self)
63    
64  class Point(Elementary):  class ReversedPrimitive(object):
65        def __init__(self,prim):
66           self.__prim=prim
67        def __getattr__(self,name):
68           if name == "getID":
69              return self.getReverseID
70           else:
71              return getattr(self.__prim,name)
72        def getReverseID(self):
73            return -self.__prim.getID()
74    
75    class Point(Primitive):
76      """      """
77      a three dimensional point      a three dimensional point
78      """      """
# Line 46  class Point(Elementary): Line 84  class Point(Elementary):
84         if not local_scale > 0.:         if not local_scale > 0.:
85             raise ValueError("local_scale needs to be positive.")             raise ValueError("local_scale needs to be positive.")
86         self._x=numarray.array([x,y,z],numarray.Float64)         self._x=numarray.array([x,y,z],numarray.Float64)
87         self.setLocalScale(0.,local_scale)         self.setLocalScale(local_scale)
     def __str__(self):  
        return str(self._x)  
88      def setLocalScale(self,factor=1.):      def setLocalScale(self,factor=1.):
89         self.__local_scale=factor         self.__local_scale=factor
90        def isPoint(self):
91            return True
92        def getLocalScale(self):
93           return self.__local_scale
94        def getCoordinates(self):
95           return self._x
96        def __add__(self,other):
97           c=self.getCoordinates()+numarray.array(other,numarray.Float64)
98           return Point(x=c[0],y=c[1],z=c[2],local_scale=self.getLocalScale())
99        def getGmshCommand(self):
100            c=self.getCoordinates()
101            return "Point(%s) = {%e , %e, %e , %e * scale};"%(self.getID(),c[0],c[1],c[2], self.getLocalScale())
102        def getHistory(self):
103            return set([self])
104    
105  class Curve(Elementary):  class Curve(Primitive):
106        """        """
107        a curve        a curve
108        """        """
# Line 64  class Curve(Elementary): Line 113  class Curve(Elementary):
113            super(Curve, self).__init__()            super(Curve, self).__init__()
114            l=len(args)            l=len(args)
115            for i in range(l):            for i in range(l):
116                if not isinstance(args[i],Point):                if not args[i].isPoint():
117                   raise TypeError("%s-th argument is not a Point object.")                   raise TypeError("%s-th argument is not a Point object."%i)
118            super(Curve, self).__init__(args[0],args[l-1])            self.__nodes=args
           self.__nodes=list(args)  
119        def __len__(self):        def __len__(self):
120            return len(self.__nodes)            return len(self.__nodes)
121          def isCurve(self):
122            return True
123          def getHistory(self):
124              out=set([self])
125              for i in self.getNodes(): out|=i.getHistory()
126              return out
127    
128        def getStart(self):        def getStart(self):
129           """           """
# Line 88  class Curve(Elementary): Line 142  class Curve(Elementary):
142           returns a list of the nodes           returns a list of the nodes
143           """           """
144           return self.__nodes           return self.__nodes
145          def __add__(self,other):
146        def __neg__(self):           return Curve([p+other for p in self.getNodes()])
147           """        def getGmshCommand(self):
148           returns the line segment with swapped start and end points          out=""
149           """          for i in self.getNodes():
150           return Curve(self.__nodes[::-1])              if len(out)>0:
151                    out+=", %s"%i.getID()
152                else:
153                    out="%s"%i.getID()
154            return "Spline(%s) = {%s};"%(self.getID(),out)
155    
156  class BezierCurve(Curve):  class BezierCurve(Curve):
157      """      """
158      a Bezier curve      a Bezier curve
159      """      """
160      def __neg__(self):      def __neg__(self):
161         """           """
162         returns the line segment with swapped start and end points           returns the line segment with swapped start and end points
163         """           """
164         return BezierCurve(self.getNodesInReversedOrder())           return BezierCurve(self.getNodes()[::-1])
165        def __add__(self,other):
166             return BezierCurve([p+other for p in self.getNodes()])
167        def getGmshCommand(self):
168            out=""
169            for i in self.getNodes():
170                if len(out)>0:
171                    out+=", %s"%i.getID()
172                else:
173                    out="%s"%i.getID()
174            return "Bezier(%s) = {%s};"%(self.getID(),out)
175    
176  class BSplineCurve(Curve):  class BSplineCurve(Curve):
177      """      """
178      a BSpline curve. Control points may be repeated.      a BSpline curve. Control points may be repeated.
179      """      """
180      def __neg__(self):      def __neg__(self):
181         """           """
182         returns the line segment with swapped start and end points           returns the line segment with swapped start and end points
183         """           """
184         return BSplineCurve(self.getNodesInReversedOrder())           return BSplineCurve(self.getNodes()[::-1])
185        def __add__(self,other):
186             return BSplineCurve([p+other for p in self.getNodes()])
187        def getGmshCommand(self):
188            out=""
189            for i in self.getNodes():
190                if len(out)>0:
191                    out+=", %s"%i.getID()
192                else:
193                    out="%s"%i.getID()
194            return "BSpline(%s) = {%s};"%(self.getID(),out)
195    
196  class Line(Curve):  class Line(Curve):
197      """      """
198      a line is defined by two L{Point}s      a line is defined by two L{Point}s
199      """      """
200        def __init__(self,start,end):
201            """
202            defines a curve form a set of control points
203            """
204            super(Line, self).__init__(start,end)
205      def __neg__(self):      def __neg__(self):
206         """         return ReversedPrimitive(self)
207         returns the line segment with swapped start and end points      def __add__(self,other):
208         """         return Line(self.getEnd()+other,self.getStart()+other)
209         return Line(self.getEnd(),self.getStart())      def getGmshCommand(self):
210            return "Line(%s) = {%s, %s};"%(self.getID(),self.getStart().getID(),self.getEnd().getID())
211    
212  class Arc(Curve):  class Arc(Curve):
213      """      """
# Line 134  class Arc(Curve): Line 217  class Arc(Curve):
217         """         """
218         creates an arc by the start point, end point and center         creates an arc by the start point, end point and center
219         """         """
220         if not isinstance(center,Point):         if center.isPoint():
221             raise TypeError("center needs to be a Point object.")             raise TypeError("center needs to be a Point object.")
222         super(Arc, self).__init__(start,end)         super(Arc, self).__init__(start,end)
223         self.__center=center         self.__center=center
# Line 144  class Arc(Curve): Line 227  class Arc(Curve):
227         returns center         returns center
228         """         """
229         return self.__center         return self.__center
230      def __neg__(self):      def __add__(self,other):
231         """         return Arc(self.getCenter()+other,self.getStart()+other,self.getEnd()+other)
232         returns the line segment with swapped start and end points  
233         """      def getHistory(self):
234         return Arc(self.getCenter(),self.getEnd(),self.getStart())            out=set([self])
235              out|=self.getCenter().getHistory()
236              for i in self.getNodes(): out|=i.getHistory()
237              return out
238        def getGmshCommand(self):
239            return "Circle(%s) = {%s, %s, %s};"%(self.getID(),self.getStart().getID(),self.getCenter().getID(),self.getEnd().getID())
240    
241  class CurveLoop(Elementary):  class CurveLoop(Primitive):
242      """      """
243      An oriented loop of curves.      An oriented loop of curves.
244    
# Line 161  class CurveLoop(Elementary): Line 249  class CurveLoop(Elementary):
249         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 closed loop.
250         """         """
251         super(CurveLoop, self).__init__()         super(CurveLoop, self).__init__()
252         for i in curves:         self.__curves=[]
253             if not isinstance(curves[i],Curve):         self.addCurve(*curves)
254                raise TypeError("%s-th argument is not a Curve object.")      def addCurve(self,*curves):
255         if length(curves)>0:         for i in range(len(curves)):
256            for i in range(len(curves)-1):             if not curves[i].isCurve():
257               if not curves[i].getEnd() == curves[i+1].getStart():                raise TypeError("%s-th argument is not a Curve object."%i)
258                   raise ValueError("start point of %s-th curve does not match end point of %s-th curve."%(i,i+1))         self.__curves+=curves
           if curves[0].getStart() == curves[len(curves)-1].getEnd():  
                  raise ValueError("loop is not closed.")  
        self.__curves=curves  
259    
260        def isCurveLoop(self):
261            return True
262      def getCurves(self):      def getCurves(self):
263         return self.__curves         return self.__curves
264        def __add__(self,other):
265      def __neg__(self):         return CurveLoop(*tuple([c+other for c in self.getCurves()[::-1]]))
        return CurveLoop([-c for c in self.__curves[::-1]])  
   
266      def __len__(self):      def __len__(self):
267         return len(self.__curves)         return len(self.__curves)
268        def getHistory(self):
269              out=set([self])
270              for i in self.getCurves(): out|=i.getHistory()
271              return out
272        def getGmshCommand(self):
273            out=""
274            for i in self.getCurves():
275                if len(out)>0:
276                    out+=", %s"%i.getID()
277                else:
278                    out="%s"%i.getID()
279            return "Line Loop(%s) = {%s};"%(self.getID(),out)
280    
281  class Surface(Elementary):  class Surface(Primitive):
282      """      """
283      a surface      a surface
284      """      """
# Line 192  class Surface(Elementary): Line 289  class Surface(Elementary):
289         @param loop: L{CurveLoop} defining the boundary of the surface         @param loop: L{CurveLoop} defining the boundary of the surface
290         """         """
291         super(Surface, self).__init__()         super(Surface, self).__init__()
292         if not isinstance(loop,CurveLoop):         if not loop.isCurveLoop():
293             raise TypeError("argument loop needs to be a CurveLoop object.")             raise TypeError("argument loop needs to be a CurveLoop object.")
294         self.__loop=loop         self.__loop=loop
295        def isSurface(self):
296            return True
297      def getBoundaryLoop(self):      def getBoundaryLoop(self):
298         return self.__loop         return self.__loop
299      def __neg__(self):      def __add__(self,other):
300         return Surface(-self.getBoundaryLoop())         return Surface(self.getBoundaryLoop()+other)
301              def getHistory(self):
302            out=set([self]) | self.getBoundaryLoop().getHistory()
303            return out
304        def getGmshCommand(self):
305            return "Ruled Surface(%s) = {%s};"%(self.getID(),self.getBoundaryLoop().getID())
306    
307  class PlaneSurface(Surface):  class PlaneSurface(Surface):
308      """      """
309      a plane surface with holes      a plane surface with holes
# Line 215  class PlaneSurface(Surface): Line 319  class PlaneSurface(Surface):
319         """         """
320         super(PlaneSurface, self).__init__(loop)         super(PlaneSurface, self).__init__(loop)
321         for i in range(len(holes)):         for i in range(len(holes)):
322              if not isinstance(holes[i],CurveLoop):              if not holes[i].inCurveLoop():
323                   raise TypeError("%i th hole needs to be a CurveLoop object.")                   raise TypeError("%i th hole needs to be a CurveLoop object.")
324         self.__holes=holes         self.__holes=holes
325      def getHoles(self):      def getHoles(self):
326         return self.__holes         return self.__holes
327      def __neg__(self):      def __add__(self,other):
328         return PlaneSurface(-self.getBoundaryLoop(),holes=[-h for h in self.getHoles()] )         return PlaneSurface(self.getBoundaryLoop()+other, holes=[h+other for h in self.getHoles()])
329        def getHistory(self):
330            out=set([self]) | self.getBoundaryLoop().getHistory()
331            for i in self.getHoles(): out|=i.getHistory()
332            return out
333        def getGmshCommand(self):
334            out=""
335            for i in self.getHoles():
336                if len(out)>0:
337                    out+=", %s"%i.getID()
338                else:
339                    out="%s"%i.getID()
340            if len(out)>0:
341              return "Plane Surface(%s) = {%s, %s};"%(self.getID(),self.getBoundaryLoop().getID(), out)
342            else:
343              return "Plane Surface(%s) = {%s};"%(self.getID(),self.getBoundaryLoop().getID())
344    
345  class RuledSurface(Surface):  class RuledSurface(Surface):
346      """      """
# Line 233  class RuledSurface(Surface): Line 352  class RuledSurface(Surface):
352    
353         @param loop: L{CurveLoop} defining the boundary of the surface. There is a restriction of composed of either three or four L{Curve} objects.         @param loop: L{CurveLoop} defining the boundary of the surface. There is a restriction of composed of either three or four L{Curve} objects.
354         """         """
355         if not isinstance(loop,CurveLoop):         if not loop.isCurveLoop():
356             raise TypeError("argument loop needs to be a CurveLoop object.")             raise TypeError("argument loop needs to be a CurveLoop object.")
357         if len(loop)<3:         if len(loop)<3:
358             raise TypeError("the loop must contain at least three Curves.")             raise TypeError("the loop must contain at least three Curves.")
359         super(RuledSurface, self).__init__(loop)         super(RuledSurface, self).__init__(loop)
360      def __neg__(self):      def __add__(self,other):
361         return RuledSurface(-self.getBoundaryLoop())         return RuledSurface(self.getBoundaryLoop()+other)
362        def getGmshCommand(self):
363            return "Ruled Surface(%s) = {%s};"%(self.getID(),self.getBoundaryLoop().getID())
364    
365  class SurfaceLoop(Elementary):  class SurfaceLoop(Primitive):
366      """      """
367      a surface loop. It defines the shell of a volume.      a surface loop. It defines the shell of a volume.
368    
# Line 252  class SurfaceLoop(Elementary): Line 373  class SurfaceLoop(Elementary):
373         creates a surface loop         creates a surface loop
374         """         """
375         super(SurfaceLoop, self).__init__()         super(SurfaceLoop, self).__init__()
376         for i in surfaces:         self.__surfaces=[]
377             if not isinstance(surfaces[i],Curve):         self.addSurface(*surfaces)
378                raise TypeError("%s-th argument is not a Curve object.")      def addSurface(self,*surfaces):
379         self.__surfaces=surfaces         for i in range(len(surfaces)):
380               if not surfaces[i].isSurface():
381                  raise TypeError("%s-th argument is not a Surface object."%i)
382           self.__surfaces+=surfaces
383    
384        def isSurfaceLoop(self):
385            return True
386      def getSurfaces(self):      def getSurfaces(self):
387         return self.__surfaces         return self.__surfaces
388        def __add__(self,other):
389      def __neg__(self):         return SurfaceLoop([c+other for c in self.getSurfaces])
        return SurfaceLoop(-c for c in self.__surfaces[::-1])  
   
390      def __len__(self):      def __len__(self):
391         return len(self.__surfaces)         return len(self.__surfaces)
392        def getHistory(self):
393              out=set([self])
394              for i in self.getSurfaces(): out|=i.getHistory()
395              return out
396        def getGmshCommand(self):
397            out=""
398            for i in self.getSurfaces():
399                if len(out)>0:
400                    out+=", %s"%i.getID()
401                else:
402                    out="%s"%i.getID()
403            return "Surface Loop(%s) = {%s};"%(self.getID(),out)
404    
405  class Volume(Elementary):  class Volume(Primitive):
406      """      """
407      a volume with holes.      a volume with holes.
408      """      """
# Line 280  class Volume(Elementary): Line 416  class Volume(Elementary):
416                A SurfaceLoop defining a hole should not have any surfaces in common with another SurfaceLoop defining a hole in the same volume.                A SurfaceLoop defining a hole should not have any surfaces in common with another SurfaceLoop defining a hole in the same volume.
417         """         """
418         super(Volume, self).__init__()         super(Volume, self).__init__()
419         if not isinstance(loop,SurfaceLoop):         if not loop.isSurfaceLoop():
420             raise TypeError("argument loop needs to be a SurfaceLoop object.")             raise TypeError("argument loop needs to be a SurfaceLoop object.")
421         for i in range(len(holes)):         for i in range(len(holes)):
422              if not isinstance(holes[i],SurfaceLoop):              if not holes[i].isSurfaceLoop():
423                   raise TypeError("%i th hole needs to be a SurfaceLoop object.")                   raise TypeError("%i th hole needs to be a SurfaceLoop object.")
424         self.__loop=loop         self.__loop=loop
425         self.__holes=holes         self.__holes=holes
# Line 291  class Volume(Elementary): Line 427  class Volume(Elementary):
427         return self.__holes         return self.__holes
428      def getSurfaceLoop(self):      def getSurfaceLoop(self):
429         return self.__loop         return self.__loop
430      def __neg__(self):      def __add__(self,other):
431         return PlaneSurface(-self.getSurfaceLoop(),holes=[-h for h in self.getHoles()] )         return Volume(self.getSurfaceLoop()+other, holes=[h+other for h in self.getHoles()])
432        def getHistory(self):
433            out=set([self]) | self.getSurfaceLoop().getHistory()
434            for i in self.getHoles(): out|=i.getHistory()
435            return out
436        def getGmshCommand(self):
437            out=""
438            for i in self.getHoles():
439                if len(out)>0:
440                    out+=", %s"%i.getID()
441                else:
442                    out="%s"%i.getID()
443            if len(out)>0:
444              return "Volume(%s) = {%s, %s};"%(self.getID(),self.getSurfaceLoop().getID(), out)
445            else:
446              return "Volume(%s) = {%s};"%(self.getID(),self.getSurfaceLoop().getID())
447    
448  class PropertySet(Elementary):  class PropertySet(Primitive):
449      """      """
450      defines a group L{Elementary} objects.      defines a group L{Primitive} objects.
451      """      """
452      def __init__(self,tag=None,*items):      def __init__(self,tag=None,*items):
453         super(PropertySet, self).__init__()         super(PropertySet, self).__init__()
454         self.__items=items         self.__items=items
455         self.__tag=tag         self.__tag=tag
456        def getHistory(self):
457            out=set([self, self.getBoundaryLoop().getHistory()])
458            for i in self.getHoles(): out|=i.getHistory()
459            return out
460    
461    class PrimitiveStack(object):
462          def __init__(self,*items):
463            self.__prims=set()
464            for i in items:
465                self.__prims|=i.getHistory()
466            self.__prims=list(self.__prims)
467            self.__prims.sort()
468    
469          def getGmshCommands(self):
470            out=""
471            for i in self.__prims:
472               out+=i.getGmshCommand()+"\n"
473            return out
474    
475          def getPycadCommands(self,name="TMP_"):
476            out=""
477            for i in self.__prims:
478               out+=i.getPycadCommand(name)+"\n"

Legend:
Removed from v.898  
changed lines
  Added in v.899

  ViewVC Help
Powered by ViewVC 1.1.26