revision 931 by gross, Fri Jan 19 03:06:33 2007 UTC revision 1388 by trankine, Fri Jan 11 07:45:58 2008 UTC
# Line 1  Line 1
1  # \$Id:\$  #
2    # \$Id\$
3    #
4    #######################################################
5    #
6    #           Copyright 2003-2007 by ACceSS MNRF
7    #       Copyright 2007 by University of Queensland
8    #
9    #                http://esscc.uq.edu.au
10    #        Primary Business: Queensland, Australia
13    #
14    #######################################################
15    #
16
17  """  """
18  Geometrical Primitives  Geometrical Primitives
# Line 27  __date__="\$Date:\$" Line 41  __date__="\$Date:\$"
41
42  import numarray  import numarray
43  from transformations import _TYPE, Translation, Dilation, Transformation  from transformations import _TYPE, Translation, Dilation, Transformation
44    from math import sqrt
45
46
47  def resetGlobalPrimitiveIdCounter():  def resetGlobalPrimitiveIdCounter():
# Line 75  class PrimitiveBase(object): Line 90  class PrimitiveBase(object):
90          """          """
91          returns the points used to construct the primitive          returns the points used to construct the primitive
92          """          """
93          out=set()          out=[]
94          for i in self.getPrimitives():          for i in self.getPrimitives():
95             if isinstance(i,Point): out.add(i)             if isinstance(i,Point): out.append(i)
96          return list(out)          return out
97
98      def getPrimitives(self):      def getPrimitives(self):
99          """          """
100          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 double entries
101          """          """
102          out=set()          out=[]
103          return list(set([p for p in self.collectPrimitiveBases()]))          for p in self.collectPrimitiveBases():
104                if not p  in out: out.append(p)
105            return out
106
107      def copy(self):      def copy(self):
108         """         """
# Line 215  class Primitive(object): Line 232  class Primitive(object):
232          """          """
233          raise NotImplementedError("__neg__ is not implemented.")          raise NotImplementedError("__neg__ is not implemented.")
234
def getGmshCommand(self, local_scaling_factor=1.):
"""
returns the Gmsh command(s) to create the primitive

@note: this class is overwritten by subclass
"""
raise NotImplementedError("getGmshCommand is not implemented.")

235      def substitute(self,sub_dict):      def substitute(self,sub_dict):
236          """          """
237          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 construct it given by the dictionary C{sub_dict}.
# Line 305  class ReversePrimitive(object): Line 314  class ReversePrimitive(object):
314            """            """
315            return self.__primitive            return self.__primitive
316
def getGmshCommand(self, local_scaling_factor=1.):
"""
returns the Gmsh command(s) to create the primitive
"""
return self.__primitive.getGmshCommand(local_scaling_factor)

317      def collectPrimitiveBases(self):      def collectPrimitiveBases(self):
318          """          """
319          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 contain primitives twice
# Line 402  class Point(Primitive, PrimitiveBase): Line 405  class Point(Primitive, PrimitiveBase):
405          self.setCoordinates(transformation(self.getCoordinates()))          self.setCoordinates(transformation(self.getCoordinates()))
406
407
def getGmshCommand(self, local_scaling_factor=1.):
"""
returns the Gmsh command(s) to create the primitive
"""
c=self.getCoordinates()
return "Point(%s) = {%s , %s, %s , %s };"%(self.getID(),c[0],c[1],c[2], self.getLocalScale()*local_scaling_factor)

408      def __neg__(self):      def __neg__(self):
409          """          """
410          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 orientiention. As a point has no direction the object itself is returned.
# Line 572  class Spline(Curve): Line 568  class Spline(Curve):
568      """      """
569      a spline curve defined through a list of control points.      a spline curve defined through a list of control points.
570      """      """
571      def getGmshCommand(self,scaling_factor=1.):      pass
"""
returns the Gmsh command(s) to create the Curve
"""
out=""
for i in self.getControlPoints():
if len(out)>0:
out+=", %s"%i.getDirectedID()
else:
out="%s"%i.getDirectedID()
return "Spline(%s) = {%s};"%(self.getID(),out)

572
573  class BezierCurve(Curve):  class BezierCurve(Curve):
574      """      """
575      a Bezier curve      a Bezier curve
576      """      """
577      def getGmshCommand(self,scaling_factor=1.):      pass
"""
returns the Gmsh command(s) to create the Curve
"""
out=""
for i in self.getControlPoints():
if len(out)>0:
out+=", %s"%i.getDirectedID()
else:
out="%s"%i.getDirectedID()
return "Bezier(%s) = {%s};"%(self.getID(),out)
578
579  class BSpline(Curve):  class BSpline(Curve):
580      """      """
581      a BSpline curve. Control points may be repeated.      a BSpline curve. Control points may be repeated.
582      """      """
583      def getGmshCommand(self,scaling_factor=1.):      pass
"""
returns the Gmsh command(s) to create the Curve
"""
out=""
for i in self.getControlPoints():
if len(out)>0:
out+=", %s"%i.getDirectedID()
else:
out="%s"%i.getDirectedID()
return "BSpline(%s) = {%s};"%(self.getID(),out)
584
585  class Line(Curve):  class Line(Curve):
586      """      """
# Line 628  class Line(Curve): Line 593  class Line(Curve):
593          if len(points)!=2:          if len(points)!=2:
594             raise TypeError("Line needs two points")             raise TypeError("Line needs two points")
595          Curve.__init__(self,*points)          Curve.__init__(self,*points)
def getGmshCommand(self,scaling_factor=1.):
"""
returns the Gmsh command(s) to create the Curve
"""
return "Line(%s) = {%s, %s};"%(self.getID(),self.getStartPoint().getDirectedID(),self.getEndPoint().getDirectedID())

596
597  class ArcBase(Manifold1D):  class ArcBase(Manifold1D):
598      def __init__(self):      def __init__(self):
# Line 669  class Arc(ArcBase, Primitive): Line 628  class Arc(ArcBase, Primitive):
628         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.")
629         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.")
630         if not isinstance(start,Point): raise TypeError("start needs to be a Point object.")         if not isinstance(start,Point): raise TypeError("start needs to be a Point object.")
631           if center.isColocated(end): raise TypeError("center and start point are colocated.")
632           if center.isColocated(start): raise TypeError("center end end point are colocated.")
633           if start.isColocated(end): raise TypeError("start and end are colocated.")
634         # TODO: check length of circle.         # TODO: check length of circle.
635         ArcBase.__init__(self)         ArcBase.__init__(self)
636         Primitive.__init__(self)         Primitive.__init__(self)
# Line 709  class Arc(ArcBase, Primitive): Line 671  class Arc(ArcBase, Primitive):
671              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))
672          return sub_dict[self]          return sub_dict[self]
673
def getGmshCommand(self,scaling_factor=1.):
"""
returns the Gmsh command(s) to create the primitive
"""
return "Circle(%s) = {%s, %s, %s};"%(self.getID(),self.getStartPoint().getDirectedID(),self.getCenterPoint().getDirectedID(),self.getEndPoint().getDirectedID())
674
675      def isColocated(self,primitive):      def isColocated(self,primitive):
676         """         """
# Line 757  class ReverseArc(ArcBase, ReversePrimiti Line 714  class ReverseArc(ArcBase, ReversePrimiti
714         """         """
715         return self.getUnderlyingPrimitive().getCenterPoint()         return self.getUnderlyingPrimitive().getCenterPoint()
716
717    class EllipseBase(Manifold1D):
718        def __init__(self):
719              """
720              create ellipse
721              """
722              Manifold1D.__init__(self)
723        def collectPrimitiveBases(self):
724           """
725           returns the primitives used to construct the Curve
726           """
727           out=[self]
728           out+=self.getStartPoint().collectPrimitiveBases()
729           out+=self.getEndPoint().collectPrimitiveBases()
730           out+=self.getCenterPoint().collectPrimitiveBases()
731           out+=self.getPointOnMainAxis().collectPrimitiveBases()
732           return out
733
734
735    class Ellipse(EllipseBase, Primitive):
736        """
737        defines an ellipse which is strictly, smaller than Pi
738        """
739        def __init__(self,center,point_on_main_axis,start,end):
740           """
741           creates an arc by the start point, end point, the center and a point on a main axis.
742           """
743           if not isinstance(center,Point): raise TypeError("center needs to be a Point object.")
744           if not isinstance(end,Point): raise TypeError("end needs to be a Point object.")
745           if not isinstance(start,Point): raise TypeError("start needs to be a Point object.")
746           if not isinstance(point_on_main_axis,Point): raise TypeError("point on main axis needs to be a Point object.")
747           if center.isColocated(end): raise TypeError("center and start point are colocated.")
748           if center.isColocated(start): raise TypeError("center end end point are colocated.")
749           if center.isColocated(point_on_main_axis): raise TypeError("center and point on main axis are colocated.")
750           if start.isColocated(end): raise TypeError("start and end point are colocated.")
751           # TODO: check length of circle.
752           EllipseBase.__init__(self)
753           Primitive.__init__(self)
754           self.__center=center
755           self.__start=start
756           self.__end=end
757           self.__point_on_main_axis=point_on_main_axis
758
759        def __neg__(self):
760              """
761              returns a view onto the curve with reversed ordering
762              """
763              return ReverseEllipse(self)
764
765        def getStartPoint(self):
766           """
767           returns start point
768           """
769           return self.__start
770
771        def getEndPoint(self):
772           """
773           returns end point
774           """
775           return self.__end
776
777        def getCenterPoint(self):
778           """
779           returns center
780           """
781           return self.__center
782
783        def getPointOnMainAxis(self):
784           """
785           returns a point on a main axis
786           """
787           return self.__point_on_main_axis
788
789        def substitute(self,sub_dict):
790            """
791            returns a copy of self with substitutes for the primitives used to construct it given by the dictionary C{sub_dict}.
792            If a substitute for the object is given by C{sub_dict} the value is returned, otherwise a new instance
793            with substituted arguments is returned.
794            """
795            if not sub_dict.has_key(self):
796                sub_dict[self]=Ellipse(self.getCenterPoint().substitute(sub_dict),
797                                       self.getPointOnMainAxis().substitute(sub_dict),
798                                       self.getStartPoint().substitute(sub_dict),
799                                       self.getEndPoint().substitute(sub_dict))
800            return sub_dict[self]
801
802
803        def isColocated(self,primitive):
804           """
805           returns True curves are on the same position
806           """
807           if hasattr(primitive,"getUnderlyingPrimitive"):
808              if isinstance(primitive.getUnderlyingPrimitive(),Ellipse):
809                self_c=self.getCenterPoint().getCoordinates()
810                p=self.getPointOnMainAxis().getCoordinates()-self_c
811                q=primitive.getPointOnMainAxis().getCoordinates()-self_c
812                # are p and q orthogonal or collinear?
813                len_p=sqrt(p[0]**2+p[1]**2+p[2]**2)
814                len_q=sqrt(q[0]**2+q[1]**2+q[2]**2)
815                p_q= abs(p[0]*q[0]+p[1]*q[1]+p[2]*q[2])
816                return ((p_q <= getToleranceForColocation() * len_q * p_q) or \
817                                       (abs(p_q - len_q * p_q) <= getToleranceForColocation())) and \
818                       self.getCenterPoint().isColocated(primitive.getCenterPoint()) and \
819                       (                                                                  \
820                            (self.getEndPoint().isColocated(primitive.getEndPoint()) and \
821                             self.getStartPoint().isColocated(primitive.getStartPoint()) ) \
822                                           or                                              \
823                             (self.getEndPoint().isColocated(primitive.getStartPoint()) and \
824                              self.getStartPoint().isColocated(primitive.getEndPoint()) ) \
825                       )
826           return False
827
828    class ReverseEllipse(EllipseBase, ReversePrimitive):
829        """
830        defines an arc which is strictly, smaller than Pi
831        """
832        def __init__(self,arc):
833           """
834           creates an instance of a reverse view to an ellipse
835           """
836           if not isinstance(arc, Ellipse):
837               raise TypeError("ReverseCurve needs to be an instance of Ellipse")
838           EllipseBase.__init__(self)
839           ReversePrimitive.__init__(self,arc)
840
841        def getStartPoint(self):
842           """
843           returns start point
844           """
845           return self.getUnderlyingPrimitive().getEndPoint()
846
847        def getEndPoint(self):
848           """
849           returns end point
850           """
851           return self.getUnderlyingPrimitive().getStartPoint()
852
853        def getCenterPoint(self):
854           """
855           returns center
856           """
857           return self.getUnderlyingPrimitive().getCenterPoint()
858
859        def getPointOnMainAxis(self):
860           """
861           returns a point on a main axis
862           """
863           return self.getUnderlyingPrimitive().getPointOnMainAxis()
864
865
866  class CurveLoop(Primitive, PrimitiveBase):  class CurveLoop(Primitive, PrimitiveBase):
867      """      """
868      An oriented loop of one-dimensional manifolds (= curves and arcs)      An oriented loop of one-dimensional manifolds (= curves and arcs)
# Line 774  class CurveLoop(Primitive, PrimitiveBase Line 880  class CurveLoop(Primitive, PrimitiveBase
880                raise TypeError("%s-th argument is not a Manifold1D object."%i)                raise TypeError("%s-th argument is not a Manifold1D object."%i)
881         # for the curves a loop:         # for the curves a loop:
882         used=[ False for i in curves]         used=[ False for i in curves]
883         self.__curves=[curves[0]]         self.__curves=list(curves)
used[0]=True
while not min(used):
found=False
for i in xrange(len(curves)):
if not used[i]:
if self.__curves[-1].getEndPoint() == curves[i].getStartPoint():
self.__curves.append(curves[i])
used[i]=True
found=True
break
raise ValueError("loop is not closed.")
if not self.__curves[0].getStartPoint() == self.__curves[-1].getEndPoint():
raise ValueError("loop is not closed.")
884         Primitive.__init__(self)         Primitive.__init__(self)
885         PrimitiveBase.__init__(self)         PrimitiveBase.__init__(self)
886
# Line 833  class CurveLoop(Primitive, PrimitiveBase Line 925  class CurveLoop(Primitive, PrimitiveBase
925
926      def isColocated(self,primitive):      def isColocated(self,primitive):
927         """         """
928         returns True if each curve is collocted with a curve in primitive         returns True if each curve is colocted with a curve in primitive
929         """         """
930         if hasattr(primitive,"getUnderlyingPrimitive"):         if hasattr(primitive,"getUnderlyingPrimitive"):
931            if isinstance(primitive.getUnderlyingPrimitive(),CurveLoop):            if isinstance(primitive.getUnderlyingPrimitive(),CurveLoop):
# Line 841  class CurveLoop(Primitive, PrimitiveBase Line 933  class CurveLoop(Primitive, PrimitiveBase
933                  cp0=self.getCurves()                  cp0=self.getCurves()
934                  cp1=primitive.getCurves()                  cp1=primitive.getCurves()
935                  for c0 in cp0:                  for c0 in cp0:
936                      collocated = False                      colocated = False
937                      for c1 in cp1:                      for c1 in cp1:
938                           collocated = collocated or c0.isColocated(c1)                           colocated = colocated or c0.isColocated(c1)
939                      if not collocated: return False                      if not colocated: return False
940                  return True                  return True
941         return False         return False
942
def getGmshCommand(self,scaling_factor=1.):
"""
returns the Gmsh command(s) to create the primitive
"""
out=""
for i in self.getCurves():
if len(out)>0:
out+=", %s"%i.getDirectedID()
else:
out="%s"%i.getDirectedID()
return "Line Loop(%s) = {%s};"%(self.getID(),out)

943  class ReverseCurveLoop(ReversePrimitive, PrimitiveBase):  class ReverseCurveLoop(ReversePrimitive, PrimitiveBase):
944      """      """
945      An oriented loop of one-dimensional manifolds (= curves and arcs)      An oriented loop of one-dimensional manifolds (= curves and arcs)
# Line 939  class RuledSurface(Primitive, Manifold2D Line 1019  class RuledSurface(Primitive, Manifold2D
1019          """          """
1020          return self.getBoundaryLoop().getCurves()          return self.getBoundaryLoop().getCurves()
1021
def getGmshCommand(self,scaling_factor=1.):
"""
returns the Gmsh command(s) to create the primitive
"""
return "Ruled Surface(%s) = {%s};"%(self.getID(),self.getBoundaryLoop().getDirectedID())

1022      def substitute(self,sub_dict):      def substitute(self,sub_dict):
1023          """          """
1024          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 construct it given by the dictionary C{sub_dict}.
# Line 957  class RuledSurface(Primitive, Manifold2D Line 1031  class RuledSurface(Primitive, Manifold2D
1031
1032      def isColocated(self,primitive):      def isColocated(self,primitive):
1033         """         """
1034         returns True if each curve is collocted with a curve in primitive         returns True if each curve is colocted with a curve in primitive
1035         """         """
1036         if hasattr(primitive,"getUnderlyingPrimitive"):         if hasattr(primitive,"getUnderlyingPrimitive"):
1037            if isinstance(primitive.getUnderlyingPrimitive(),RuledSurface):            if isinstance(primitive.getUnderlyingPrimitive(),RuledSurface):
# Line 1017  class PlaneSurface(Primitive, Manifold2D Line 1091  class PlaneSurface(Primitive, Manifold2D
1091         """         """
1092         if not isinstance(loop.getUnderlyingPrimitive(),CurveLoop):         if not isinstance(loop.getUnderlyingPrimitive(),CurveLoop):
1093             raise TypeError("argument loop needs to be a CurveLoop object.")             raise TypeError("argument loop needs to be a CurveLoop object.")
for l in loop.getCurves():
if not isinstance(l.getUnderlyingPrimitive(),Line):
raise TypeError("loop may be formed by Lines only.")
1094         for i in range(len(holes)):         for i in range(len(holes)):
1095              if not isinstance(holes[i].getUnderlyingPrimitive(), CurveLoop):              if not isinstance(holes[i].getUnderlyingPrimitive(), CurveLoop):
1096                   raise TypeError("%i-th hole needs to be a CurveLoop object.")                   raise TypeError("%i-th hole needs to be a CurveLoop object.")
for l in holes[i].getCurves():
if not isinstance(l.getUnderlyingPrimitive(),Line):
raise TypeError("holes may be formed by Lines only.")
1097         #TODO: check if lines and holes are in a plane         #TODO: check if lines and holes are in a plane
1098         #TODO: are holes really holes?         #TODO: are holes really holes?
1099         Primitive.__init__(self)         Primitive.__init__(self)
# Line 1044  class PlaneSurface(Primitive, Manifold2D Line 1112  class PlaneSurface(Primitive, Manifold2D
1112          """          """
1113          return self.__loop          return self.__loop
1114
def getGmshCommand(self,scaling_factor=1.):
"""
returns the Gmsh command(s) to create the primitive
"""
out=""
for i in self.getHoles():
if len(out)>0:
out+=", %s"%i.getDirectedID()
else:
out="%s"%i.getDirectedID()
if len(out)>0:
return "Plane Surface(%s) = {%s, %s};"%(self.getID(),self.getBoundaryLoop().getDirectedID(), out)
else:
return "Plane Surface(%s) = {%s};"%(self.getID(),self.getBoundaryLoop().getDirectedID())

1115      def substitute(self,sub_dict):      def substitute(self,sub_dict):
1116          """          """
1117          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 construct it given by the dictionary C{sub_dict}.
# Line 1071  class PlaneSurface(Primitive, Manifold2D Line 1124  class PlaneSurface(Primitive, Manifold2D
1124
1125      def isColocated(self,primitive):      def isColocated(self,primitive):
1126         """         """
1127         returns True if each curve is collocted with a curve in primitive         returns True if each curve is colocted with a curve in primitive
1128         """         """
1129         if hasattr(primitive,"getUnderlyingPrimitive"):         if hasattr(primitive,"getUnderlyingPrimitive"):
1130            if isinstance(primitive.getUnderlyingPrimitive(),PlaneSurface):            if isinstance(primitive.getUnderlyingPrimitive(),PlaneSurface):
# Line 1080  class PlaneSurface(Primitive, Manifold2D Line 1133  class PlaneSurface(Primitive, Manifold2D
1133                  hs1=primitive.getHoles()                  hs1=primitive.getHoles()
1134                  if len(hs0) == len(hs1):                  if len(hs0) == len(hs1):
1135                      for h0 in hs0:                      for h0 in hs0:
1136                         collocated = False                         colocated = False
1137                         for h1 in hs1:                         for h1 in hs1:
1138                           collocated = collocated or h0.isColocated(h1)                           colocated = colocated or h0.isColocated(h1)
1139                         if not collocated: return False                         if not colocated: return False
1140                      return True                      return True
1141         return False         return False
1142      def collectPrimitiveBases(self):      def collectPrimitiveBases(self):
# Line 1156  class SurfaceLoop(Primitive, PrimitiveBa Line 1209  class SurfaceLoop(Primitive, PrimitiveBa
1209         for i in range(len(surfaces)):         for i in range(len(surfaces)):
1210             if not isinstance(surfaces[i].getUnderlyingPrimitive(),Manifold2D):             if not isinstance(surfaces[i].getUnderlyingPrimitive(),Manifold2D):
1211                raise TypeError("%s-th argument is not a Manifold2D object."%i)                raise TypeError("%s-th argument is not a Manifold2D object."%i)
1212           self.__surfaces=list(surfaces)
1213         Primitive.__init__(self)         Primitive.__init__(self)
1214         PrimitiveBase.__init__(self)         PrimitiveBase.__init__(self)
# for the curves a loop:
used=[ False for s in surfaces]
self.__surfaces=[surfaces[0]]
used[0]= True
edges=[ e for e in surfaces[0].getBoundary() ]
used_edges=[ False for e in surfaces[0].getBoundary() ]
while not min(used):
found=False
for i in xrange(len(surfaces)):
if not used[i]:
i_boundary=surfaces[i].getBoundary()
for ib in xrange(len(i_boundary)):
if i_boundary[ib] in edges:
found=True
break
if found:
used[i]=True
self.__surfaces.append(surfaces[i])
for ib in xrange(len(i_boundary)):
if i_boundary[ib] in edges:
if used_edges[edges.index(i_boundary[ib])]:
raise ValueError("boundary segment %s is shared by more than one surface."%str(i_boundary[ib].getUnderlyingPrimitive()))
used_edges[edges.index(i_boundary[ib])]=True
else:
edges.append(i_boundary[ib])
used_edges.append(False)
break
raise ValueError("loop is not closed.")
if not min(used_edges):
raise ValueError("loop is not closed. Surface is missing.")
1215      def __len__(self):      def __len__(self):
1216         """         """
1217         return the number of curves in the SurfaceLoop         return the number of curves in the SurfaceLoop
# Line 1215  class SurfaceLoop(Primitive, PrimitiveBa Line 1238  class SurfaceLoop(Primitive, PrimitiveBa
1238         for c in self.getSurfaces(): out+=c.collectPrimitiveBases()         for c in self.getSurfaces(): out+=c.collectPrimitiveBases()
1239         return out         return out
1240
def getGmshCommand(self,scaling_factor=1.):
"""
returns the Gmsh command(s) to create the primitive
"""
out=""
for i in self.getSurfaces():
if len(out)>0:
out+=", %s"%i.getDirectedID()
else:
out="%s"%i.getDirectedID()
return "Surface Loop(%s) = {%s};"%(self.getID(),out)

1241      def substitute(self,sub_dict):      def substitute(self,sub_dict):
1242          """          """
1243          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 construct it given by the dictionary C{sub_dict}.
# Line 1241  class SurfaceLoop(Primitive, PrimitiveBa Line 1252  class SurfaceLoop(Primitive, PrimitiveBa
1252
1253      def isColocated(self,primitive):      def isColocated(self,primitive):
1254         """         """
1255         returns True if each surface is collocted with a curve in primitive and vice versa.         returns True if each surface is colocted with a curve in primitive and vice versa.
1256         """         """
1257         if hasattr(primitive,"getUnderlyingPrimitive"):         if hasattr(primitive,"getUnderlyingPrimitive"):
1258           if isinstance(primitive.getUnderlyingPrimitive(),SurfaceLoop):           if isinstance(primitive.getUnderlyingPrimitive(),SurfaceLoop):
# Line 1249  class SurfaceLoop(Primitive, PrimitiveBa Line 1260  class SurfaceLoop(Primitive, PrimitiveBa
1260                  sp0=self.getSurfaces()                  sp0=self.getSurfaces()
1261                  sp1=primitive.getSurfaces()                  sp1=primitive.getSurfaces()
1262                  for s0 in sp0:                  for s0 in sp0:
1263                      collocated = False                      colocated = False
1264                      for s1 in sp1:                      for s1 in sp1:
1265                           collocated = collocated or s0.isColocated(s1)                           colocated = colocated or s0.isColocated(s1)
1266                      if not collocated: return False                      if not colocated: return False
1267                  return True                  return True
1268         return False         return False
1269
# Line 1333  class Volume(Manifold3D, Primitive): Line 1344  class Volume(Manifold3D, Primitive):
1344         """         """
1345         return self.__loop         return self.__loop
1346
def getGmshCommand(self,scaling_factor=1.):
"""
returns the Gmsh command(s) to create the primitive
"""
out=""
for i in self.getHoles():
if len(out)>0:
out+=", %s"%i.getDirectedID()
else:
out="%s"%i.getDirectedID()
if len(out)>0:
return "Volume(%s) = {%s, %s};"%(self.getID(),self.getSurfaceLoop().getDirectedID(), out)
else:
return "Volume(%s) = {%s};"%(self.getID(),self.getSurfaceLoop().getDirectedID())

1347      def substitute(self,sub_dict):      def substitute(self,sub_dict):
1348          """          """
1349          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 construct it given by the dictionary C{sub_dict}.
# Line 1360  class Volume(Manifold3D, Primitive): Line 1356  class Volume(Manifold3D, Primitive):
1356
1357      def isColocated(self,primitive):      def isColocated(self,primitive):
1358         """         """
1359         returns True if each curve is collocted with a curve in primitive         returns True if each curve is colocted with a curve in primitive
1360         """         """
1361         if hasattr(primitive,"getUnderlyingPrimitive"):         if hasattr(primitive,"getUnderlyingPrimitive"):
1362            if isinstance(primitive.getUnderlyingPrimitive(),Volume):            if isinstance(primitive.getUnderlyingPrimitive(),Volume):
# Line 1369  class Volume(Manifold3D, Primitive): Line 1365  class Volume(Manifold3D, Primitive):
1365                  hs1=primitive.getHoles()                  hs1=primitive.getHoles()
1366                  if len(hs0) == len(hs1):                  if len(hs0) == len(hs1):
1367                      for h0 in hs0:                      for h0 in hs0:
1368                         collocated = False                         colocated = False
1369                         for h1 in hs1:                         for h1 in hs1:
1370                           collocated = collocated or h0.isColocated(h1)                           colocated = colocated or h0.isColocated(h1)
1371                         if not collocated: return False                         if not colocated: return False
1372                      return True                      return True
1373         return False         return False
1374      def collectPrimitiveBases(self):      def collectPrimitiveBases(self):
# Line 1390  class Volume(Manifold3D, Primitive): Line 1386  class Volume(Manifold3D, Primitive):
1386          for h in self.getHoles(): out+=h.getSurfaces()          for h in self.getHoles(): out+=h.getSurfaces()
1387          return out          return out
1388
1389  class PropertySet(PrimitiveBase):  class PropertySet(Primitive, PrimitiveBase):
1390      """      """
1391      defines a group L{PrimitiveBase} objects.      defines a group of L{Primitive} which can be accessed through a name
1392      """      """
1393      def __init__(self,tag=None,*items):      def __init__(self,name,*items):
1394         super(PropertySet, self).__init__()         Primitive.__init__(self)
1395         self.__items=items         self.__dim=None
1396         self.__tag=tag         self.clearItems()
1398           self.setName(name)
1399
1400        def getDim(self):
1401           """
1402           returns the dimension of the items
1403           """
1404           if self.__dim == None:
1405               items=self.getItems()
1406               if len(items)>0:
1407                    if isinstance(items[0] ,Manifold1D):
1408                         self.__dim=1
1409                    elif isinstance(items[0] ,Manifold2D):
1410                         self.__dim=2
1411                    elif isinstance(items[0] ,Manifold3D):
1412                        self.__dim=3
1413                    else:
1414                        self.__dim=0
1415           return self.__dim
1416        def __repr__(self):
1417           """
1418           returns a string representation
1419           """
1420           return "%s(%s)"%(self.getName(),self.getID())
1421        def getManifoldClass(self):
1422            """
1423            returns the manifold class expected from items
1424            """
1425            d=self.getDim()
1426            if d == None:
1427               raise ValueError("undefined spatial diemnsion.")
1428            else:
1429               if d==0:
1430                  return Point
1431               elif d==1:
1432                  return Manifold1D
1433               elif d==2:
1434                  return Manifold2D
1435               else:
1436                  return Manifold3D
1437
1438        def getName(self):
1439            """
1440            returns the name of the set
1441            """
1442            return self.__name
1443        def setName(self,name):
1444            """
1445            sets the name.
1446            """
1447            self.__name=str(name)
1448
1450            """
1451            adds items. An item my be any L{Primitive} but no L{PropertySet}
1452            """
1454
1456            """
1457            adds items. An item my be any L{Primitive} but no L{PropertySet}
1458            """
1459            for i in items:
1460                if not i in self.__items:
1461                   if len(self.__items)>0:
1462                      m=self.getManifoldClass()
1463                      if not isinstance(i, m):
1464                         raise TypeError("argument %s is not a %s class object."%(i, m.__name__))
1465                   self.__items.append(i)
1466        def getNumItems(self):
1467            """
1468            returns the number of items in the property set
1469            """
1470            return len(self.__items)
1471
1472        def getItems(self):
1473            """
1474            returns the list of items
1475            """
1476            return self.__items
1477
1478        def clearItems(self):
1479            """
1480            clears the list of items
1481            """
1482            self.__items=[]
1483      def collectPrimitiveBases(self):      def collectPrimitiveBases(self):
1484          out=[self]+self.getBoundaryLoop().collectPrimitiveBases()          """
1485          for i in self.getHoles(): out+=i.collectPrimitiveBases()          returns primitives used to construct the PropertySet
1486            """
1487            out=[self]
1488            for i in self.getItems(): out+=i.collectPrimitiveBases()
1489          return out          return out
1490
1491        def getTag(self):
1492             """
1493             returns the tag used for this property set
1494             """
1495             return self.getID()

Legend:
 Removed from v.931 changed lines Added in v.1388