]> SALOME platform Git repositories - modules/shaper.git/blob - src/PythonAPI/model/sketcher/sketch.py
Salome HOME
[PythonAPI] derived sketcher interfaces from Interface base class
[modules/shaper.git] / src / PythonAPI / model / sketcher / sketch.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 modelAPI_ResultConstruction, featureToCompositeFeature
7 from GeomDataAPI import geomDataAPI_Point, geomDataAPI_Dir
8 from GeomAlgoAPI import GeomAlgoAPI_SketchBuilder, ShapeList
9 from model.sketcher.point import Point
10 from model.sketcher.line import Line
11 from model.sketcher.circle import Circle
12 from model.sketcher.arc import Arc
13 from model.roots import Interface
14
15 def addSketch(doc, plane):
16     """Add a Sketch feature to the Part or PartSet and return an interface
17     on it.
18     
19     A Sketch object is instanciated with a feature as input parameter
20     it provides an interface for manipulation of the feature data.
21     :return: interface on the feature
22     :rtype: Sketch"""
23     feature = featureToCompositeFeature(doc.addFeature("Sketch"))
24     return Sketch(feature, plane)
25
26 class Sketch(Interface):
27     """Interface on a Sketch feature."""
28     def __init__(self, feature, plane):
29         """Initialize a 2D Sketch on the given plane.
30         
31         The plane can be defined either by:
32         - a 3D axis system (geom.Ax3),
33         - an existing face identified by its topological name.
34         """
35         Interface.__init__(self, feature)
36         assert(self._feature.getKind() == "Sketch")
37         
38         # Entities used for building the result shape
39         self._selection = None
40         #   self.resultype ="Face" # Type of Sketch result
41         if isinstance(plane, str):
42             self.__sketchOnFace(plane)
43         else:
44             self.__sketchOnPlane(plane)
45
46     def __sketchOnPlane(self, plane):
47         """Create the sketch on a plane."""
48         origin = plane.location()
49         normal = plane.direction()
50         x_direction = plane.xDirection()
51         geomDataAPI_Point( 
52             self._feature.data().attribute("Origin") 
53             ).setValue(origin.x(), origin.y(), origin.z())
54         geomDataAPI_Dir( 
55             self._feature.data().attribute("DirX") 
56             ).setValue(x_direction.x(), x_direction.y(), x_direction.z())
57         geomDataAPI_Dir( 
58             self._feature.data().attribute("Norm") 
59             ).setValue(normal.x(), normal.y(), normal.z() )
60
61     def __sketchOnFace(self, name):
62         """Initialize the sketch on a face given by its name."""
63         self._feature.data().selection("External").selectSubShape("FACE", name)
64
65     #-------------------------------------------------------------
66     #
67     # Creation of Geometries
68     #
69     #-------------------------------------------------------------
70
71     def addPoint(self, *args):
72         """Add a point to this Sketch."""
73         point_feature = self._feature.addFeature("SketchPoint")
74         return Point(point_feature, *args)
75
76     def addLine(self, *args):
77         """Add a line to this Sketch."""
78         line_feature = self._feature.addFeature("SketchLine")
79         line_interface = Line(line_feature, *args)
80         # if the line is created by name add a rigid constraint
81         # to the created line
82         if len(args) == 1 and isinstance(args[0], str):
83             constraint = sketch.addFeature("SketchConstraintRigid")
84             constraint.refattr("ConstraintEntityA").setObject(
85                 line_feature.firstResult()
86                 )
87         return line_interface
88     
89     def addCircle(self, *args):
90         """Add a circle to this Sketch."""
91         circle_feature = self._feature.addFeature("SketchCircle")
92         return Circle(circle_feature, *args)
93     
94     def addArc(self, *args):
95         """Add an arc to this Sketch."""
96         arc_feature = self._feature.addFeature("SketchArc")
97         return Arc(arc_feature, *args)
98   
99     #-------------------------------------------------------------
100     #
101     # Creation of Geometrical and Dimensional Constraints
102     #
103     #-------------------------------------------------------------
104
105     def setCoincident(self, p1, p2):
106         """Set coincident the two given points and add the corresponding 
107         constraint to this Sketch."""
108         constraint = self._feature.addFeature("SketchConstraintCoincidence")
109         constraint.data().refattr("ConstraintEntityA").setAttr(p1)
110         constraint.data().refattr("ConstraintEntityB").setAttr(p2)
111         return constraint
112
113     def setParallel(self, l1, l2):
114         """Set parallel the two given lines and add the corresponding 
115         constraint to this Sketch."""
116         constraint = self._feature.addFeature("SketchConstraintParallel")
117         constraint.data().refattr("ConstraintEntityA").setObject(l1)
118         constraint.data().refattr("ConstraintEntityB").setObject(l2)
119         return constraint
120
121     def setPerpendicular(self, l1, l2):
122         """Set perpendicular the two given lines and add the corresponding 
123         constraint to this Sketch."""
124         constraint = self._feature.addFeature("SketchConstraintPerpendicular")
125         constraint.data().refattr("ConstraintEntityA").setObject(l1)
126         constraint.data().refattr("ConstraintEntityB").setObject(l2)
127         return constraint
128     
129     def setHorizontal(self, line):
130         """Set horizontal the given line and add the corresponding 
131         constraint to this Sketch."""
132         constraint = self._feature.addFeature("SketchConstraintHorizontal")
133         constraint.data().refattr("ConstraintEntityA").setObject(line)
134         return constraint
135     
136     def setVertical(self, line):
137         """Set vertical the given line and add the corresponding 
138         constraint to this Sketch."""
139         constraint = self._feature.addFeature("SketchConstraintVertical")
140         constraint.data().refattr("ConstraintEntityA").setObject(line)
141         return constraint
142
143     def setDistance(self, point, line, length):
144         """Set the distance between the given point and line, and add
145         the corresponding constraint to this Sketch."""
146         constraint = self._feature.addFeature("SketchConstraintDistance")
147         if isinstance(line, str):
148             # Add the edge identified by the given topological name 
149             # to this Sketch
150             line = self.addLine(line).result()   
151         constraint.data().refattr("ConstraintEntityA").setAttr(point)
152         constraint.data().refattr("ConstraintEntityB").setObject(line)
153         constraint.data().real("ConstraintValue").setValue(length)
154         self._feature.execute()
155         return constraint
156
157     def setLength(self, line, length):
158         """Set the length of the given line and add the corresponding 
159         constraint to this Sketch."""
160         constraint = self._feature.addFeature("SketchConstraintLength")
161         constraint.data().refattr("ConstraintEntityA").setObject(line)
162         constraint.data().real("ConstraintValue").setValue(length)
163         self._feature.execute()
164         return constraint
165     
166     def setRadius(self, circle, radius):
167         """Set the radius of the given circle and add the corresponding 
168         constraint to this Sketch."""
169         constraint = self._feature.addFeature("SketchConstraintRadius")
170         constraint.data().refattr("ConstraintEntityA").setObject(circle)
171         constraint.data().real("ConstraintValue").setValue(radius)
172         return constraint
173     
174     def setEqual(self, object_1, object_2):
175         """Set the radii of two circles or the length of two lines equal.
176         
177         The corresponding constraint is added to the sketch"""
178         constraint = self._feature.addFeature("SketchConstraintEqual")
179         constraint.data().refattr("ConstraintEntityA").setObject(object_1)
180         constraint.data().refattr("ConstraintEntityB").setObject(object_2)
181         self._feature.execute()
182         return constraint
183     
184     def setAngle(self, line_1, line_2, angle):
185         """Set the angle between the given 2 lines and add the corresponding 
186         constraint to the sketch."""
187         constraint = self._feature.addFeature("SketchConstraintAngle")
188         constraint.data().refattr("ConstraintEntityA").setObject(line_1)
189         constraint.data().refattr("ConstraintEntityB").setObject(line_2)
190         constraint.data().real("ConstraintValue").setValue(angle)
191         self._feature.execute()
192         return constraint
193     
194     def setTangent(self, object_1, object_2):
195         """Set a tangential continuity between two objects 
196         at their coincidence point."""
197         constraint = self._feature.addFeature("SketchConstraintTangent")
198         constraint.data().refattr("ConstraintEntityA").setObject(object_1)
199         constraint.data().refattr("ConstraintEntityB").setObject(object_2)
200         self._feature.execute()
201         return constraint
202     
203     def setFillet(self, line_1, line_2, radius):
204         """Set a fillet constraint between the 3 given lines with the given 
205         filleting radius."""
206         constraint = self._feature.addFeature("SketchConstraintFillet")
207         constraint.data().refattr("ConstraintEntityA").setObject(line_1)
208         constraint.data().refattr("ConstraintEntityB").setObject(line_2)
209         constraint.data().real("ConstraintValue").setValue(radius)
210         self._feature.execute()
211         return constraint
212
213     #-------------------------------------------------------------
214     #
215     # Edition of Dimensional Constraints
216     #
217     #-------------------------------------------------------------
218
219     def setValue(self, constraint, value):
220         """Modify the value of the given dimensional constraint."""
221         constraint.data().real("ConstraintValue").setValue(value)
222      
223     #-------------------------------------------------------------
224     #
225     # Macro functions combining geometry creation and constraints
226     #
227     #-------------------------------------------------------------
228      
229     def addPolyline(self, *coords):
230         """Add a poly-line to this Sketch.
231         
232         The end of consecutive segments are defined as coincident.
233         """
234         c0 = coords[0]
235         c1 = coords[1]
236         polyline = []
237         line_1 = self.addLine(c0, c1)
238         polyline.append(line_1)
239         # Adding and connecting next lines
240         for c2 in coords[2:]:
241             line_2 = self.addLine(c1, c2)
242             self.setCoincident(line_1.endPointData(), line_2.startPointData())
243             polyline.append(line_2)
244             c1 = c2
245             line_1 = line_2
246         return polyline
247
248     def addPolygon(self, *coords):
249         """Add a polygon to this Sketch.
250         
251         The end of consecutive segments are defined as coincident.
252         """
253         pg = self.addPolyline(*coords)
254         # Closing the poly-line supposed being defined by at least 3 points
255         c0 = coords[0]
256         cn = coords[len(coords) - 1]
257         ln = self.addLine(cn, c0)
258         self.setCoincident(
259             pg[len(coords) - 2].endPointData(), ln.startPointData()
260             )
261         self.setCoincident(
262             ln.endPointData(), pg[0].startPointData()
263             )
264         pg.append(ln)
265         return pg
266
267     #-------------------------------------------------------------
268     #
269     # Getters
270     #
271     #-------------------------------------------------------------
272
273     def selectFace(self, *args):
274         """Select the geometrical entities of this Sketch on which 
275         the result Face must be built.
276         
277         When no entity is given, the face is based on all existing 
278         geometry of this Sketch.
279         """
280         if len(args) == 0:
281             self._selection = modelAPI_ResultConstruction( 
282                 self._feature.firstResult()).shape()
283         elif len(args) == 1:
284             self._selection = args[0].shape()
285         else:
286             raise Exception("not yet implemented")
287         return self
288
289     def buildShape(self):
290         """Build the result Shape of this Sketch according to the 
291         selected geometrical entities."""
292         o  = geomDataAPI_Point( self._feature.data().attribute("Origin") ).pnt()
293         dx = geomDataAPI_Dir( self._feature.data().attribute("DirX") ).dir()
294         n  = geomDataAPI_Dir( self._feature.data().attribute("Norm") ).dir()
295
296         # The faces are kept otherwise they are destroyed at exit
297         faces = ShapeList()
298         GeomAlgoAPI_SketchBuilder.createFaces(o, dx, n, self._selection, faces)
299         #TODO: Deal with several faces 
300         return faces[0]
301
302     def result(self):
303         """Returns the result data of this Feature."""
304         return self._feature.firstResult()