1 """Sketch Feature Interface
2 Author: Daniel Brunier-Coulin with contribution by Mikhail Ponikarov
3 finalized by Renaud Nedelec and Sergey Pokhodenko
4 Copyright (C) 2014-20xx CEA/DEN, EDF R&D
7 from ModelAPI import modelAPI_ResultConstruction, featureToCompositeFeature
8 from GeomDataAPI import geomDataAPI_Point, geomDataAPI_Dir
9 from GeomAlgoAPI import GeomAlgoAPI_SketchBuilder, ShapeList
11 from model.sketcher.point import Point
12 from model.sketcher.line import Line
13 from model.sketcher.circle import Circle
14 from model.sketcher.arc import Arc
15 from model.roots import Interface
16 from model.tools import Selection
19 def addSketch(doc, plane):
20 """Add a Sketch feature to the Part or PartSet and return an interface
23 A Sketch object is instanciated with a feature as input parameter
24 it provides an interface for manipulation of the feature data.
25 :return: interface on the feature
27 feature = featureToCompositeFeature(doc.addFeature("Sketch"))
28 return Sketch(feature, plane)
30 class Sketch(Interface):
31 """Interface class for Sketch feature."""
32 def __init__(self, feature, *args):
33 """Initialize a 2D Sketch on the given plane.
35 The plane can be defined either by:
36 - a 3D axis system (geom.Ax3),
37 - an existing face identified by its topological name.
39 Interface.__init__(self, feature)
40 assert(self._feature.getKind() == "Sketch")
42 self._origin = geomDataAPI_Point(
43 self._feature.data().attribute("Origin")
45 self._dir_x = geomDataAPI_Dir(
46 self._feature.data().attribute("DirX")
48 self._norm = geomDataAPI_Dir(
49 self._feature.data().attribute("Norm")
51 self._external = self._feature.data().selection("External")
56 assert(self._external)
63 # self.resultype ="Face" # Type of Sketch result
64 if isinstance(plane, str):
65 self.__sketchOnFace(plane)
67 self.__sketchOnPlane(plane)
70 def __sketchOnPlane(self, plane):
71 """Create the sketch on a plane."""
72 origin = plane.location()
73 normal = plane.direction()
74 x_direction = plane.xDirection()
75 self._origin.setValue(origin.x(), origin.y(), origin.z())
76 self._norm.setValue(normal.x(), normal.y(), normal.z())
77 self._dir_x.setValue(x_direction.x(), x_direction.y(), x_direction.z())
79 def __sketchOnFace(self, name):
80 """Initialize the sketch on a face given by its name."""
81 self._external.selectSubShape("FACE", name)
83 #-------------------------------------------------------------
85 # Creation of Geometries
87 #-------------------------------------------------------------
89 def addPoint(self, *args):
90 """Add a point to this Sketch."""
91 point_feature = self._feature.addFeature("SketchPoint")
92 return Point(point_feature, *args)
94 def addLine(self, *args):
95 """Add a line to this Sketch."""
96 line_feature = self._feature.addFeature("SketchLine")
97 line_interface = Line(line_feature, *args)
98 # if the line is created by name add a rigid constraint
100 if len(args) == 1 and isinstance(args[0], str):
101 constraint = self._feature.addFeature("SketchConstraintRigid")
102 constraint.refattr("ConstraintEntityA").setObject(
103 line_feature.firstResult()
105 return line_interface
107 def addCircle(self, *args):
108 """Add a circle to this Sketch."""
109 circle_feature = self._feature.addFeature("SketchCircle")
110 return Circle(circle_feature, *args)
112 def addArc(self, *args):
113 """Add an arc to this Sketch."""
114 arc_feature = self._feature.addFeature("SketchArc")
115 return Arc(arc_feature, *args)
117 #-------------------------------------------------------------
119 # Creation of Geometrical and Dimensional Constraints
121 #-------------------------------------------------------------
123 def setCoincident(self, p1, p2):
124 """Set coincident the two given points and add the corresponding
125 constraint to this Sketch."""
127 constraint = self._feature.addFeature("SketchConstraintCoincidence")
128 constraint.data().refattr("ConstraintEntityA").setAttr(p1)
129 constraint.data().refattr("ConstraintEntityB").setAttr(p2)
133 def setParallel(self, l1, l2):
134 """Set parallel the two given lines and add the corresponding
135 constraint to this Sketch."""
137 constraint = self._feature.addFeature("SketchConstraintParallel")
138 constraint.data().refattr("ConstraintEntityA").setObject(l1)
139 constraint.data().refattr("ConstraintEntityB").setObject(l2)
143 def setPerpendicular(self, l1, l2):
144 """Set perpendicular the two given lines and add the corresponding
145 constraint to this Sketch."""
147 constraint = self._feature.addFeature("SketchConstraintPerpendicular")
148 constraint.data().refattr("ConstraintEntityA").setObject(l1)
149 constraint.data().refattr("ConstraintEntityB").setObject(l2)
153 def setHorizontal(self, line):
154 """Set horizontal the given line and add the corresponding
155 constraint to this Sketch."""
156 constraint = self._feature.addFeature("SketchConstraintHorizontal")
157 constraint.data().refattr("ConstraintEntityA").setObject(line)
161 def setVertical(self, line):
162 """Set vertical the given line and add the corresponding
163 constraint to this Sketch."""
164 constraint = self._feature.addFeature("SketchConstraintVertical")
165 constraint.data().refattr("ConstraintEntityA").setObject(line)
169 def setDistance(self, point, line, length):
170 """Set the distance between the given point and line, and add
171 the corresponding constraint to this Sketch."""
172 assert(point and line)
173 constraint = self._feature.addFeature("SketchConstraintDistance")
174 if isinstance(line, basestring):
175 # Add the edge identified by the given topological name
177 line = self.addLine(line).result()
179 constraint.data().refattr("ConstraintEntityA").setAttr(point)
180 constraint.data().refattr("ConstraintEntityB").setObject(line)
181 constraint.data().real("ConstraintValue").setValue(length)
185 def setLength(self, line, length):
186 """Set the length of the given line and add the corresponding
187 constraint to this Sketch."""
189 constraint = self._feature.addFeature("SketchConstraintLength")
190 constraint.data().refattr("ConstraintEntityA").setObject(line)
191 constraint.data().real("ConstraintValue").setValue(length)
195 def setRadius(self, circle, radius):
196 """Set the radius of the given circle and add the corresponding
197 constraint to this Sketch."""
198 constraint = self._feature.addFeature("SketchConstraintRadius")
199 constraint.data().refattr("ConstraintEntityA").setObject(circle)
200 constraint.data().real("ConstraintValue").setValue(radius)
204 def setEqual(self, object_1, object_2):
205 """Set the radii of two circles or the length of two lines equal.
207 The corresponding constraint is added to the sketch"""
208 constraint = self._feature.addFeature("SketchConstraintEqual")
209 constraint.data().refattr("ConstraintEntityA").setObject(object_1)
210 constraint.data().refattr("ConstraintEntityB").setObject(object_2)
214 def setAngle(self, line_1, line_2, angle):
215 """Set the angle between the given 2 lines and add the corresponding
216 constraint to the sketch."""
217 constraint = self._feature.addFeature("SketchConstraintAngle")
218 constraint.data().refattr("ConstraintEntityA").setObject(line_1)
219 constraint.data().refattr("ConstraintEntityB").setObject(line_2)
220 constraint.data().real("ConstraintValue").setValue(angle)
224 def setTangent(self, object_1, object_2):
225 """Set a tangential continuity between two objects
226 at their coincidence point."""
227 constraint = self._feature.addFeature("SketchConstraintTangent")
228 constraint.data().refattr("ConstraintEntityA").setObject(object_1)
229 constraint.data().refattr("ConstraintEntityB").setObject(object_2)
233 def setFillet(self, line_1, line_2, radius):
234 """Set a fillet constraint between the 3 given lines with the given
236 constraint = self._feature.addFeature("SketchConstraintFillet")
237 constraint.data().refattr("ConstraintEntityA").setObject(line_1)
238 constraint.data().refattr("ConstraintEntityB").setObject(line_2)
239 constraint.data().real("ConstraintValue").setValue(radius)
243 #-------------------------------------------------------------
245 # Edition of Dimensional Constraints
247 #-------------------------------------------------------------
249 def setValue(self, constraint, value):
250 """Modify the value of the given dimensional constraint."""
251 constraint.data().real("ConstraintValue").setValue(value)
253 #-------------------------------------------------------------
255 # Macro functions combining geometry creation and constraints
257 #-------------------------------------------------------------
259 def addPolyline(self, *coords):
260 """Add a poly-line to this Sketch.
262 The end of consecutive segments are defined as coincident.
267 line_1 = self.addLine(c0, c1)
268 polyline.append(line_1)
269 # Adding and connecting next lines
270 for c2 in coords[2:]:
271 line_2 = self.addLine(c1, c2)
272 self.setCoincident(line_1.endPointData(), line_2.startPointData())
273 polyline.append(line_2)
278 def addPolygon(self, *coords):
279 """Add a polygon to this Sketch.
281 The end of consecutive segments are defined as coincident.
283 pg = self.addPolyline(*coords)
284 # Closing the poly-line supposed being defined by at least 3 points
286 cn = coords[len(coords) - 1]
287 ln = self.addLine(cn, c0)
289 pg[len(coords) - 2].endPointData(), ln.startPointData()
292 ln.endPointData(), pg[0].startPointData()
297 #-------------------------------------------------------------
301 #-------------------------------------------------------------
303 def selectFace(self, *args):
304 """Select the geometrical entities of this Sketch on which
305 the result Face must be built.
307 When no entity is given, the face is based on all existing
308 geometry of this Sketch.
311 wire = modelAPI_ResultConstruction(
312 self._feature.firstResult()
315 wire = args[0].shape()
317 raise Exception("not yet implemented")
318 # TODO: simple version now, should be a list of selected faces
319 return [Selection(self.result(), self.buildShape(wire))]
321 def buildShape(self, wire):
322 """Build the result Shape of this Sketch according to the
323 selected geometrical entities."""
324 o = self._origin.pnt()
325 dx = self._dir_x.dir()
328 # The faces are kept otherwise they are destroyed at exit
330 GeomAlgoAPI_SketchBuilder.createFaces(o, dx, n, wire, faces)
331 # TODO: Deal with several faces
335 """Returns the result data of this Feature."""
336 return self._feature.firstResult()