1 """Sketch Feature Interface
2 Author: Daniel Brunier-Coulin with contribution by Mikhail Ponikarov
3 Copyright (C) 2014-20xx CEA/DEN, EDF R&D
6 from ModelAPI import modelAPI_ResultConstruction, featureToCompositeFeature
7 from GeomDataAPI import geomDataAPI_Point, geomDataAPI_Dir
8 from GeomAlgoAPI import GeomAlgoAPI_SketchBuilder, ShapeList
10 from model.sketcher.point import Point
11 from model.sketcher.line import Line
12 from model.sketcher.circle import Circle
13 from model.sketcher.arc import Arc
14 from model.roots import Interface
15 from model.tools import Selection
18 def addSketch(doc, plane):
19 """Add a Sketch feature to the Part or PartSet and return an interface
22 A Sketch object is instanciated with a feature as input parameter
23 it provides an interface for manipulation of the feature data.
24 :return: interface on the feature
26 feature = featureToCompositeFeature(doc.addFeature("Sketch"))
27 return Sketch(feature, plane)
29 class Sketch(Interface):
30 """Interface class for Sketch feature."""
31 def __init__(self, feature, *args):
32 """Initialize a 2D Sketch on the given plane.
34 The plane can be defined either by:
35 - a 3D axis system (geom.Ax3),
36 - an existing face identified by its topological name.
38 Interface.__init__(self, feature)
39 assert(self._feature.getKind() == "Sketch")
41 self._origin = geomDataAPI_Point(
42 self._feature.data().attribute("Origin")
44 self._dir_x = geomDataAPI_Dir(
45 self._feature.data().attribute("DirX")
47 self._norm = geomDataAPI_Dir(
48 self._feature.data().attribute("Norm")
50 self._external = self._feature.data().selection("External")
55 assert(self._external)
62 # self.resultype ="Face" # Type of Sketch result
63 if isinstance(plane, str):
64 self.__sketchOnFace(plane)
66 self.__sketchOnPlane(plane)
69 def __sketchOnPlane(self, plane):
70 """Create the sketch on a plane."""
71 origin = plane.location()
72 normal = plane.direction()
73 x_direction = plane.xDirection()
74 self._origin.setValue(origin.x(), origin.y(), origin.z())
75 self._norm.setValue(normal.x(), normal.y(), normal.z())
76 self._dir_x.setValue(x_direction.x(), x_direction.y(), x_direction.z())
78 def __sketchOnFace(self, name):
79 """Initialize the sketch on a face given by its name."""
80 self._external.selectSubShape("FACE", name)
82 #-------------------------------------------------------------
84 # Creation of Geometries
86 #-------------------------------------------------------------
88 def addPoint(self, *args):
89 """Add a point to this Sketch."""
90 point_feature = self._feature.addFeature("SketchPoint")
91 return Point(point_feature, *args)
93 def addLine(self, *args):
94 """Add a line to this Sketch."""
95 line_feature = self._feature.addFeature("SketchLine")
96 line_interface = Line(line_feature, *args)
97 # if the line is created by name add a rigid constraint
99 if len(args) == 1 and isinstance(args[0], str):
100 constraint = self._feature.addFeature("SketchConstraintRigid")
101 constraint.refattr("ConstraintEntityA").setObject(
102 line_feature.firstResult()
104 return line_interface
106 def addCircle(self, *args):
107 """Add a circle to this Sketch."""
108 circle_feature = self._feature.addFeature("SketchCircle")
109 return Circle(circle_feature, *args)
111 def addArc(self, *args):
112 """Add an arc to this Sketch."""
113 arc_feature = self._feature.addFeature("SketchArc")
114 return Arc(arc_feature, *args)
116 #-------------------------------------------------------------
118 # Creation of Geometrical and Dimensional Constraints
120 #-------------------------------------------------------------
122 def setCoincident(self, p1, p2):
123 """Set coincident the two given points and add the corresponding
124 constraint to this Sketch."""
126 constraint = self._feature.addFeature("SketchConstraintCoincidence")
127 constraint.data().refattr("ConstraintEntityA").setAttr(p1)
128 constraint.data().refattr("ConstraintEntityB").setAttr(p2)
132 def setParallel(self, l1, l2):
133 """Set parallel the two given lines and add the corresponding
134 constraint to this Sketch."""
136 constraint = self._feature.addFeature("SketchConstraintParallel")
137 constraint.data().refattr("ConstraintEntityA").setObject(l1)
138 constraint.data().refattr("ConstraintEntityB").setObject(l2)
142 def setPerpendicular(self, l1, l2):
143 """Set perpendicular the two given lines and add the corresponding
144 constraint to this Sketch."""
146 constraint = self._feature.addFeature("SketchConstraintPerpendicular")
147 constraint.data().refattr("ConstraintEntityA").setObject(l1)
148 constraint.data().refattr("ConstraintEntityB").setObject(l2)
152 def setHorizontal(self, line):
153 """Set horizontal the given line and add the corresponding
154 constraint to this Sketch."""
155 constraint = self._feature.addFeature("SketchConstraintHorizontal")
156 constraint.data().refattr("ConstraintEntityA").setObject(line)
160 def setVertical(self, line):
161 """Set vertical the given line and add the corresponding
162 constraint to this Sketch."""
163 constraint = self._feature.addFeature("SketchConstraintVertical")
164 constraint.data().refattr("ConstraintEntityA").setObject(line)
168 def setDistance(self, point, line, length):
169 """Set the distance between the given point and line, and add
170 the corresponding constraint to this Sketch."""
171 assert(point and line)
172 constraint = self._feature.addFeature("SketchConstraintDistance")
173 if isinstance(line, basestring):
174 # Add the edge identified by the given topological name
176 line = self.addLine(line).result()
178 constraint.data().refattr("ConstraintEntityA").setAttr(point)
179 constraint.data().refattr("ConstraintEntityB").setObject(line)
180 constraint.data().real("ConstraintValue").setValue(length)
184 def setLength(self, line, length):
185 """Set the length of the given line and add the corresponding
186 constraint to this Sketch."""
188 constraint = self._feature.addFeature("SketchConstraintLength")
189 constraint.data().refattr("ConstraintEntityA").setObject(line)
190 constraint.data().real("ConstraintValue").setValue(length)
194 def setRadius(self, circle, radius):
195 """Set the radius of the given circle and add the corresponding
196 constraint to this Sketch."""
197 constraint = self._feature.addFeature("SketchConstraintRadius")
198 constraint.data().refattr("ConstraintEntityA").setObject(circle)
199 constraint.data().real("ConstraintValue").setValue(radius)
203 def setEqual(self, object_1, object_2):
204 """Set the radii of two circles or the length of two lines equal.
206 The corresponding constraint is added to the sketch"""
207 constraint = self._feature.addFeature("SketchConstraintEqual")
208 constraint.data().refattr("ConstraintEntityA").setObject(object_1)
209 constraint.data().refattr("ConstraintEntityB").setObject(object_2)
213 def setAngle(self, line_1, line_2, angle):
214 """Set the angle between the given 2 lines and add the corresponding
215 constraint to the sketch."""
216 constraint = self._feature.addFeature("SketchConstraintAngle")
217 constraint.data().refattr("ConstraintEntityA").setObject(line_1)
218 constraint.data().refattr("ConstraintEntityB").setObject(line_2)
219 constraint.data().real("ConstraintValue").setValue(angle)
223 def setTangent(self, object_1, object_2):
224 """Set a tangential continuity between two objects
225 at their coincidence point."""
226 constraint = self._feature.addFeature("SketchConstraintTangent")
227 constraint.data().refattr("ConstraintEntityA").setObject(object_1)
228 constraint.data().refattr("ConstraintEntityB").setObject(object_2)
232 def setFillet(self, line_1, line_2, radius):
233 """Set a fillet constraint between the 3 given lines with the given
235 constraint = self._feature.addFeature("SketchConstraintFillet")
236 constraint.data().refattr("ConstraintEntityA").setObject(line_1)
237 constraint.data().refattr("ConstraintEntityB").setObject(line_2)
238 constraint.data().real("ConstraintValue").setValue(radius)
242 #-------------------------------------------------------------
244 # Edition of Dimensional Constraints
246 #-------------------------------------------------------------
248 def setValue(self, constraint, value):
249 """Modify the value of the given dimensional constraint."""
250 constraint.data().real("ConstraintValue").setValue(value)
252 #-------------------------------------------------------------
254 # Macro functions combining geometry creation and constraints
256 #-------------------------------------------------------------
258 def addPolyline(self, *coords):
259 """Add a poly-line to this Sketch.
261 The end of consecutive segments are defined as coincident.
266 line_1 = self.addLine(c0, c1)
267 polyline.append(line_1)
268 # Adding and connecting next lines
269 for c2 in coords[2:]:
270 line_2 = self.addLine(c1, c2)
271 self.setCoincident(line_1.endPointData(), line_2.startPointData())
272 polyline.append(line_2)
277 def addPolygon(self, *coords):
278 """Add a polygon to this Sketch.
280 The end of consecutive segments are defined as coincident.
282 pg = self.addPolyline(*coords)
283 # Closing the poly-line supposed being defined by at least 3 points
285 cn = coords[len(coords) - 1]
286 ln = self.addLine(cn, c0)
288 pg[len(coords) - 2].endPointData(), ln.startPointData()
291 ln.endPointData(), pg[0].startPointData()
296 #-------------------------------------------------------------
300 #-------------------------------------------------------------
302 def selectFace(self, *args):
303 """Select the geometrical entities of this Sketch on which
304 the result Face must be built.
306 When no entity is given, the face is based on all existing
307 geometry of this Sketch.
310 wire = modelAPI_ResultConstruction(
311 self._feature.firstResult()
314 wire = args[0].shape()
316 raise Exception("not yet implemented")
317 # TODO: simple version now, should be a list of selected faces
318 return [Selection(self.result(), self.buildShape(wire))]
320 def buildShape(self, wire):
321 """Build the result Shape of this Sketch according to the
322 selected geometrical entities."""
323 o = self._origin.pnt()
324 dx = self._dir_x.dir()
327 # The faces are kept otherwise they are destroyed at exit
329 GeomAlgoAPI_SketchBuilder.createFaces(o, dx, n, wire, faces)
330 # TODO: Deal with several faces
334 """Returns the result data of this Feature."""
335 return self._feature.firstResult()