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