Salome HOME
[PythonAPI] added two tests and added transaction commit step in
[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 *
7 from GeomDataAPI import *
8 from GeomAlgoAPI import *
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
14 def addSketch(doc, plane):
15     """Add a Sketch feature to the Part or PartSet and return an interface
16     on it.
17     
18     A Sketch object is instanciated with a feature as input parameter
19     it provides an interface for manipulation of the feature data.
20     :return: interface on the feature
21     :rtype: Sketch object"""
22     feature = featureToCompositeFeature(doc.addFeature("Sketch"))
23     return Sketch(feature, plane)
24
25 class Sketch():
26     """Interface on a Sketch feature."""
27     def __init__(self, feature, plane):
28         """Initialize a 2D Sketch on the given plane.
29         
30         The plane can be defined either by:
31         - a 3D axis system (geom.Ax3),
32         - an existing face identified by its topological name.
33         """
34         self._feature = feature
35         # Entities used for building the result shape
36         self._selection = None
37         #   self.resultype ="Face" # Type of Sketch result
38         if isinstance(plane, str):
39             self.__sketchOnFace(plane)
40         else:
41             self.__sketchOnPlane(plane)
42
43     def __sketchOnPlane (self, plane):
44         o  = plane.location()
45         d  = plane.direction()
46         dx = plane.xDirection()
47         geomDataAPI_Point( 
48             self._feature.data().attribute("Origin") 
49             ).setValue( o.x(), o.y(), o.z() )
50         geomDataAPI_Dir( 
51             self._feature.data().attribute("DirX") 
52             ).setValue( dx.x(), dx.y(), dx.z() )
53         geomDataAPI_Dir( 
54             self._feature.data().attribute("Norm") 
55             ).setValue( d.x(),  d.y(),  d.z()  )
56
57     def __sketchOnFace (self, plane):
58         self._feature.data().selection("External").selectSubShape("FACE", plane)
59
60
61     # Creation of Geometries
62
63     def addPoint (self, *args):
64         """Add a point to this Sketch."""
65         point_feature = self._feature.addFeature("SketchPoint")
66         return Point(point_feature, *args)
67
68     def addLine (self, *args):
69         """Add a line to this Sketch."""
70         line_feature = self._feature.addFeature("SketchLine")
71         return Line(line_feature, *args)
72     
73     def addCircle (self, *args):
74         """Add a circle to this Sketch."""
75         circle_feature = self._feature.addFeature("SketchCircle")
76         return Circle(circle_feature, *args)
77     
78     def addArc (self, *args):
79         """Add an arc to this Sketch."""
80         arc_feature = self._feature.addFeature("SketchArc")
81         return Arc(arc_feature, *args)
82
83     # Creation of Geometrical and Dimensional Constraints
84
85     def setCoincident (self, p1, p2):
86         """Set coincident the two given points and add the corresponding 
87         constraint to this Sketch."""
88         constraint = self._feature.addFeature("SketchConstraintCoincidence")
89         constraint.data().refattr("ConstraintEntityA").setAttr(p1)
90         constraint.data().refattr("ConstraintEntityB").setAttr(p2)
91         return constraint
92
93     def setParallel (self, l1, l2):
94         """Set parallel the two given lines and add the corresponding 
95         constraint to this Sketch."""
96         constraint = self._feature.addFeature("SketchConstraintParallel")
97         constraint.data().refattr("ConstraintEntityA").setObject(l1)
98         constraint.data().refattr("ConstraintEntityB").setObject(l2)
99         return constraint
100
101     def setPerpendicular (self, l1, l2):
102         """Set perpendicular the two given lines and add the corresponding 
103         constraint to this Sketch."""
104         constraint = self._feature.addFeature("SketchConstraintPerpendicular")
105         constraint.data().refattr("ConstraintEntityA").setObject(l1)
106         constraint.data().refattr("ConstraintEntityB").setObject(l2)
107         return constraint
108
109     def setDistance (self, point, line, length):
110         """Set the distance between the given point and line, and add
111         the corresponding constraint to this Sketch."""
112         constraint = self._feature.addFeature("SketchConstraintDistance")
113         if isinstance(line, str):
114             # Add the edge identified by the given topological name 
115             # to this Sketch
116             line = self.addLine(line).result()   
117         constraint.data().refattr("ConstraintEntityA").setAttr(point)
118         constraint.data().refattr("ConstraintEntityB").setObject(line)
119         constraint.data().real("ConstraintValue").setValue(length)
120         self._feature.execute()
121         return constraint
122
123     def setLength (self, line, length):
124         """Set the length of the given line and add the corresponding 
125         constraint to this Sketch."""
126         constraint = self._feature.addFeature("SketchConstraintLength")
127         constraint.data().refattr("ConstraintEntityA").setObject(line)
128         constraint.data().real("ConstraintValue").setValue(length)
129         self._feature.execute()
130         return constraint
131
132     def setRadius (self, circle, radius):
133         """Set the radius of the given circle and add the corresponding 
134         constraint to this Sketch."""
135         constraint = self._feature.addFeature("SketchConstraintRadius")
136         constraint.data().refattr("ConstraintEntityA").setObject(circle)
137         constraint.data().real("ConstraintValue").setValue(radius)
138         return constraint
139
140
141     # Edition of Dimensional Constraints
142
143     def setValue (self, constraint, value):
144         """Modify the value of the given dimensional constraint."""
145         constraint.data().real("ConstraintValue").setValue(value)
146      
147      
148     # Macro functions combining geometry creation and constraints
149      
150     def addPolyline (self, *coords):
151         """Add a poly-line to this Sketch.
152         
153         The end of consecutive segments are defined as coincident.
154         """
155         c0 = coords[0]
156         c1 = coords[1]
157         polyline = []
158         line_1 = self.addLine(c0, c1)
159         polyline.append(line_1)
160         # Adding and connecting next lines
161         for c2 in coords[2:]:
162             line_2 = self.addLine(c1, c2)
163             self.setCoincident(line_1.endPointData(), line_2.startPointData())
164             polyline.append(line_2)
165             c1 = c2
166             line_1 = line_2
167         return polyline
168
169     def addPolygon (self, *coords):
170         """Add a polygon to this Sketch.
171         
172         The end of consecutive segments are defined as coincident.
173         """
174         pg = self.addPolyline(*coords)
175         # Closing the poly-line supposed being defined by at least 3 points
176         c0 = coords[0]
177         cn = coords[len(coords) - 1]
178         ln = self.addLine(cn, c0)
179         self.setCoincident(
180             pg[len(coords) - 2].endPointData(), ln.startPointData()
181             )
182         self.setCoincident(
183             ln.endPointData(), pg[0].startPointData()
184             )
185         pg.append(ln)
186         return pg
187
188
189     # Getters
190
191     def selectFace (self, *args):
192         """Select the geometrical entities of this Sketch on which 
193         the result Face must be built.
194         
195         When no entity is given, the face is based on all existing 
196         geometry of this Sketch.
197         """
198         #self.resultype ="Face"
199         if   len(args) == 0:
200             self._selection = modelAPI_ResultConstruction( 
201                 self._feature.firstResult()).shape()
202         elif len(args) == 1:
203             self._selection = args[0].shape()
204         else:
205             raise Exception("not yet implemented")
206         return self
207
208     def buildShape (self):
209         """Builds the result Shape of this Sketch according to the selected geometrical entities."""
210         o  = geomDataAPI_Point( self._feature.data().attribute("Origin") ).pnt()
211         dx = geomDataAPI_Dir( self._feature.data().attribute("DirX") ).dir()
212         n  = geomDataAPI_Dir( self._feature.data().attribute("Norm") ).dir()
213
214         faces = ShapeList()      # The faces are kept otherwise they are destroyed at exit
215         GeomAlgoAPI_SketchBuilder.createFaces(o, dx, n, self._selection, faces)
216     #TODO: Deal with several faces 
217         return faces[0]
218
219     def result (self):
220         """Returns the result data of this Feature."""
221         return self._feature.firstResult()