Salome HOME
Documenting of Python code
[modules/shaper.git] / src / PythonAPI / modeler / sketcher.py
1 """Sketch Feature Interface
2 Author: Daniel Brunier-Coulin with contribution by Mikhail Ponikarov
3 Copyright (C) 2014-20xx CEA/DEN, EDF R&D
4 """
5
6 from ModelAPI    import *
7 from GeomDataAPI import *
8 from GeomAlgoAPI import *
9
10
11 class Sketch():
12   """ A class of Sketcher"""
13
14   def __init__(self, doc, plane):
15     """Initializes a 2D Sketch on the given plane and adds the Sketch to the given Part or Partset.
16         The plane can be defined either by:
17         - a 3D axis system (geom.Ax3),
18         - an existing face identified by its topological name.
19     """
20     ### Create a feature object
21     self.my = featureToCompositeFeature( doc.addFeature("Sketch") )
22     ### Entities used for building the result shape
23     self.selection = None         
24 #   self.resultype ="Face"        # Type of Sketch result
25     if isinstance(plane, str):
26       self.__sketchOnFace(doc, plane)
27     else:
28       self.__sketchOnPlane(doc, plane)
29
30   def __sketchOnPlane (self, doc, plane):
31     o  = plane.location()
32     d  = plane.direction()
33     dx = plane.xDirection()
34     geomDataAPI_Point( self.my.data().attribute("Origin") ).setValue( o.x(), o.y(), o.z() )
35     geomDataAPI_Dir( self.my.data().attribute("DirX") ).setValue( dx.x(), dx.y(), dx.z() )
36     geomDataAPI_Dir( self.my.data().attribute("Norm") ).setValue( d.x(),  d.y(),  d.z()  )
37
38   def __sketchOnFace (self, doc, plane):
39     self.my.data().selection("External").selectSubShape("FACE", plane)
40
41
42 # Creation of Geometries
43
44   def addPoint (self, *args):
45     """Adds a point to this Sketch."""
46     return Point(self.my, *args)
47
48   def addLine (self, *args):
49     """Adds a line to this Sketch."""
50     return Line(self.my, *args)
51
52   def addPolyline (self, *coords):
53     """Adds a poly-line to this Sketch.
54     The end of consecutive segments are defined as coincident.
55     """
56     c0 = coords[0]
57     c1 = coords[1]
58     pl = []
59     l1 = self.addLine(c0, c1)
60     pl.append(l1)
61     # Adding and connecting next lines
62     for c2 in coords[2:]:
63       l2 = self.addLine(c1, c2)
64       self.setCoincident( l1.endPointData(), l2.startPointData() )
65       pl.append(l2)
66       c1 = c2
67       l1 = l2
68     return pl
69
70   def addPolygon (self, *coords):
71     """Adds a polygon to this Sketch.
72     The end of consecutive segments are defined as coincident.
73     """
74     pg = self.addPolyline(*coords)
75         # Closing the poly-line supposed being defined by at least 3 points
76     c0 = coords[0]
77     cn = coords[len(coords)-1]
78     ln = self.addLine(cn, c0)
79     self.setCoincident( pg[len(coords)-2].endPointData(), ln.startPointData() )
80     self.setCoincident( ln.endPointData(), pg[0].startPointData() )
81     pg.append(ln)
82     return pg
83
84   def addCircle (self, *args):
85     """Adds a circle to this Sketch."""
86     return Circle(self.my, *args)
87
88
89 # Creation of Geometrical and Dimensional Constraints
90
91   def setCoincident (self, p1, p2):
92     """Sets coincident the two given points and adds the corresponding constraint to this Sketch."""
93     constraint = self.my.addFeature("SketchConstraintCoincidence")
94     constraint.data().refattr("ConstraintEntityA").setAttr(p1)
95     constraint.data().refattr("ConstraintEntityB").setAttr(p2)
96     return constraint
97
98   def setParallel (self, l1, l2):
99     """Sets parallel the two given lines and adds the corresponding constraint to this Sketch."""
100     constraint = self.my.addFeature("SketchConstraintParallel")
101     constraint.data().refattr("ConstraintEntityA").setObject(l1)
102     constraint.data().refattr("ConstraintEntityB").setObject(l2)
103     return constraint
104
105   def setPerpendicular (self, l1, l2):
106     """Sets perpendicular the two given lines and adds the corresponding constraint to this Sketch."""
107     constraint = self.my.addFeature("SketchConstraintPerpendicular")
108     constraint.data().refattr("ConstraintEntityA").setObject(l1)
109     constraint.data().refattr("ConstraintEntityB").setObject(l2)
110     return constraint
111
112   def setDistance (self, point, line, length):
113     """Sets the distance between the given point and line, and adds the corresponding constraint to this Sketch."""
114     constraint = self.my.addFeature("SketchConstraintDistance")
115     if isinstance(line, str):
116       line = self.addLine(line).result()   # Adds the edge identified by the given topological name to this Sketch
117     constraint.data().refattr("ConstraintEntityA").setAttr(point)
118     constraint.data().refattr("ConstraintEntityB").setObject(line)
119     constraint.data().real("ConstraintValue").setValue(length)
120     self.my.execute()
121     return constraint
122
123   def setLength (self, line, length):
124     """Sets the length of the given line and adds the corresponding constraint to this Sketch."""
125     constraint = self.my.addFeature("SketchConstraintLength")
126     constraint.data().refattr("ConstraintEntityA").setObject(line)
127     constraint.data().real("ConstraintValue").setValue(length)
128     self.my.execute()
129     return constraint
130
131   def setRadius (self, circle, radius):
132     """Sets the radius of the given circle and adds the corresponding constraint to this Sketch."""
133     constraint = self.my.addFeature("SketchConstraintRadius")
134     constraint.data().refattr("ConstraintEntityA").setObject(circle)
135     constraint.data().real("ConstraintValue").setValue(radius)
136     return constraint
137
138
139 # Edition of Dimensional Constraints
140
141   def setValue (self, constraint, value):
142     """Modifies the value of the given dimensional constraint."""
143     constraint.data().real("ConstraintValue").setValue(value)
144
145
146 # Getters
147
148   def selectFace (self, *args):
149     """Selects the geometrical entities of this Sketch on which the result Face must be built.
150         When no entity is given, the face is based on all existing geometry of this Sketch.
151         """
152     #self.resultype ="Face"
153     if   len(args) == 0:
154       self.selection = modelAPI_ResultConstruction( self.my.firstResult() ).shape()
155     elif len(args) == 1:
156       self.selection = args[0].shape()
157     else:
158       raise Exception("not yet implemented")
159     return self
160
161   def buildShape (self):
162     """Builds the result Shape of this Sketch according to the selected geometrical entities."""
163     o  = geomDataAPI_Point( self.my.data().attribute("Origin") ).pnt()
164     dx = geomDataAPI_Dir( self.my.data().attribute("DirX") ).dir()
165     n  = geomDataAPI_Dir( self.my.data().attribute("Norm") ).dir()
166
167     faces = ShapeList()      # The faces are kept otherwise they are destroyed at exit
168     GeomAlgoAPI_SketchBuilder.createFaces(o, dx, n, self.selection, faces)
169 #TODO: Deal with several faces 
170     return faces[0]
171
172   def result (self):
173     """Returns the result data of this Feature."""
174     return self.my.firstResult()
175
176
177 # Class definitions of Sketch features
178
179 class Point():
180   """A class which represents a Point object"""
181
182   def __init__(self, sketch, x, y):
183     """Constructor"""
184     ### Create the feature
185     self.my = sketch.addFeature("SketchPoint")
186     geomDataAPI_Point2D( self.my.data().attribute("PointCoordindates") ).setValue(x, y)
187     self.my.execute()
188
189   def pointData (self):
190     """Returns points attribute"""
191     return geomDataAPI_Point2D( self.my.data().attribute("PointCoordindates") )
192
193   def result (self):
194     """Returns result object"""
195     return self.my.firstResult()
196
197
198 class Line():
199   """A class which represents a Line object"""
200
201   def __init__(self, sketch, *args):
202     """Constructor"""
203     ### Create the feature
204     self.my = sketch.addFeature("SketchLine")
205     if   len(args) == 4:
206       self.__createByCoordinates(*args)
207     elif len(args) == 2:
208       self.__createByPoints(*args)
209     elif len(args) == 1:
210           self.__createByName(sketch, *args)
211     else:
212       raise Exception("cannot create the Line")
213
214   def __createByCoordinates(self, x1, y1, x2, y2):
215     """Initialise the feature by coordinates"""
216     geomDataAPI_Point2D( self.my.data().attribute("StartPoint") ).setValue(x1, y1)
217     geomDataAPI_Point2D( self.my.data().attribute("EndPoint") ).setValue(x2, y2)
218     self.my.execute()
219
220   def __createByPoints(self, p1, p2):
221     """Initialise the feature by point objects"""
222     geomDataAPI_Point2D( self.my.data().attribute("StartPoint") ).setValue(p1.x(), p1.y())
223     geomDataAPI_Point2D( self.my.data().attribute("EndPoint") ).setValue(p2.x(), p2.y())
224     self.my.execute()
225
226   def __createByName(self, sketch, name):
227     """Initialise the feature by name of edge"""
228     self.my.data().selection("External").selectSubShape("EDGE", name)
229     self.my.execute()
230     rigid = sketch.addFeature("SketchConstraintRigid")
231     rigid.refattr("ConstraintEntityA").setObject( self.my.firstResult() )
232
233   def startPointData (self):
234     """Returns start point"""
235     return geomDataAPI_Point2D( self.my.data().attribute("StartPoint") )
236
237   def endPointData (self):
238     """Returns end point"""
239     return geomDataAPI_Point2D( self.my.data().attribute("EndPoint") )
240
241   def result (self):
242     """Returns result"""
243     return self.my.firstResult()
244
245
246 class Circle():
247   """A class which represents a Circle object"""
248
249   def __init__(self, sketch, x, y, r):
250     """Constructor"""
251     ### Create the feature
252     self.my = sketch.addFeature("SketchCircle")
253     geomDataAPI_Point2D( self.my.data().attribute("CircleCenter") ).setValue(x, y)
254     self.my.data().real("CircleRadius").setValue(r)
255     self.my.execute()
256
257   def centerData (self):
258     """Returns center point"""
259     return geomDataAPI_Point2D( self.my.data().attribute("CircleCenter") )
260
261   def result (self):
262     """Returns result"""
263     return self.my.lastResult()   # Returns the circular line attribute
264
265