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 on a 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)
57 # Entities used for building the result shape
58 self._selection = None
65 # self.resultype ="Face" # Type of Sketch result
66 if isinstance(plane, str):
67 self.__sketchOnFace(plane)
69 self.__sketchOnPlane(plane)
71 def __sketchOnPlane(self, plane):
72 """Create the sketch on a plane."""
73 origin = plane.location()
74 normal = plane.direction()
75 x_direction = plane.xDirection()
76 self._origin.setValue(origin.x(), origin.y(), origin.z())
77 self._norm.setValue(normal.x(), normal.y(), normal.z())
78 self._dir_x.setValue(x_direction.x(), x_direction.y(), x_direction.z())
80 def __sketchOnFace(self, name):
81 """Initialize the sketch on a face given by its name."""
82 self._external.selectSubShape("FACE", name)
84 #-------------------------------------------------------------
86 # Creation of Geometries
88 #-------------------------------------------------------------
90 def addPoint(self, *args):
91 """Add a point to this Sketch."""
92 point_feature = self._feature.addFeature("SketchPoint")
93 return Point(point_feature, *args)
95 def addLine(self, *args):
96 """Add a line to this Sketch."""
97 line_feature = self._feature.addFeature("SketchLine")
98 line_interface = Line(line_feature, *args)
99 # if the line is created by name add a rigid constraint
100 # to the created line
101 if len(args) == 1 and isinstance(args[0], str):
102 constraint = self._feature.addFeature("SketchConstraintRigid")
103 constraint.refattr("ConstraintEntityA").setObject(
104 line_feature.firstResult()
106 return line_interface
108 def addCircle(self, *args):
109 """Add a circle to this Sketch."""
110 circle_feature = self._feature.addFeature("SketchCircle")
111 return Circle(circle_feature, *args)
113 def addArc(self, *args):
114 """Add an arc to this Sketch."""
115 arc_feature = self._feature.addFeature("SketchArc")
116 return Arc(arc_feature, *args)
118 #-------------------------------------------------------------
120 # Creation of Geometrical and Dimensional Constraints
122 #-------------------------------------------------------------
124 def setCoincident(self, p1, p2):
125 """Set coincident the two given points and add the corresponding
126 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."""
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."""
145 constraint = self._feature.addFeature("SketchConstraintPerpendicular")
146 constraint.data().refattr("ConstraintEntityA").setObject(l1)
147 constraint.data().refattr("ConstraintEntityB").setObject(l2)
151 def setHorizontal(self, line):
152 """Set horizontal the given line and add the corresponding
153 constraint to this Sketch."""
154 constraint = self._feature.addFeature("SketchConstraintHorizontal")
155 constraint.data().refattr("ConstraintEntityA").setObject(line)
159 def setVertical(self, line):
160 """Set vertical the given line and add the corresponding
161 constraint to this Sketch."""
162 constraint = self._feature.addFeature("SketchConstraintVertical")
163 constraint.data().refattr("ConstraintEntityA").setObject(line)
167 def setDistance(self, point, line, length):
168 """Set the distance between the given point and line, and add
169 the corresponding constraint to this Sketch."""
170 constraint = self._feature.addFeature("SketchConstraintDistance")
171 if isinstance(line, str):
172 # Add the edge identified by the given topological name
174 line = self.addLine(line).result()
175 constraint.data().refattr("ConstraintEntityA").setAttr(point)
176 constraint.data().refattr("ConstraintEntityB").setObject(line)
177 constraint.data().real("ConstraintValue").setValue(length)
181 def setLength(self, line, length):
182 """Set the length of the given line and add the corresponding
183 constraint to this Sketch."""
184 constraint = self._feature.addFeature("SketchConstraintLength")
185 constraint.data().refattr("ConstraintEntityA").setObject(line)
186 constraint.data().real("ConstraintValue").setValue(length)
190 def setRadius(self, circle, radius):
191 """Set the radius of the given circle and add the corresponding
192 constraint to this Sketch."""
193 constraint = self._feature.addFeature("SketchConstraintRadius")
194 constraint.data().refattr("ConstraintEntityA").setObject(circle)
195 constraint.data().real("ConstraintValue").setValue(radius)
199 def setEqual(self, object_1, object_2):
200 """Set the radii of two circles or the length of two lines equal.
202 The corresponding constraint is added to the sketch"""
203 constraint = self._feature.addFeature("SketchConstraintEqual")
204 constraint.data().refattr("ConstraintEntityA").setObject(object_1)
205 constraint.data().refattr("ConstraintEntityB").setObject(object_2)
209 def setAngle(self, line_1, line_2, angle):
210 """Set the angle between the given 2 lines and add the corresponding
211 constraint to the sketch."""
212 constraint = self._feature.addFeature("SketchConstraintAngle")
213 constraint.data().refattr("ConstraintEntityA").setObject(line_1)
214 constraint.data().refattr("ConstraintEntityB").setObject(line_2)
215 constraint.data().real("ConstraintValue").setValue(angle)
219 def setTangent(self, object_1, object_2):
220 """Set a tangential continuity between two objects
221 at their coincidence point."""
222 constraint = self._feature.addFeature("SketchConstraintTangent")
223 constraint.data().refattr("ConstraintEntityA").setObject(object_1)
224 constraint.data().refattr("ConstraintEntityB").setObject(object_2)
228 def setFillet(self, line_1, line_2, radius):
229 """Set a fillet constraint between the 3 given lines with the given
231 constraint = self._feature.addFeature("SketchConstraintFillet")
232 constraint.data().refattr("ConstraintEntityA").setObject(line_1)
233 constraint.data().refattr("ConstraintEntityB").setObject(line_2)
234 constraint.data().real("ConstraintValue").setValue(radius)
238 #-------------------------------------------------------------
240 # Edition of Dimensional Constraints
242 #-------------------------------------------------------------
244 def setValue(self, constraint, value):
245 """Modify the value of the given dimensional constraint."""
246 constraint.data().real("ConstraintValue").setValue(value)
248 #-------------------------------------------------------------
250 # Macro functions combining geometry creation and constraints
252 #-------------------------------------------------------------
254 def addPolyline(self, *coords):
255 """Add a poly-line to this Sketch.
257 The end of consecutive segments are defined as coincident.
262 line_1 = self.addLine(c0, c1)
263 polyline.append(line_1)
264 # Adding and connecting next lines
265 for c2 in coords[2:]:
266 line_2 = self.addLine(c1, c2)
267 self.setCoincident(line_1.endPointData(), line_2.startPointData())
268 polyline.append(line_2)
273 def addPolygon(self, *coords):
274 """Add a polygon to this Sketch.
276 The end of consecutive segments are defined as coincident.
278 pg = self.addPolyline(*coords)
279 # Closing the poly-line supposed being defined by at least 3 points
281 cn = coords[len(coords) - 1]
282 ln = self.addLine(cn, c0)
284 pg[len(coords) - 2].endPointData(), ln.startPointData()
287 ln.endPointData(), pg[0].startPointData()
292 #-------------------------------------------------------------
296 #-------------------------------------------------------------
298 def selectFace(self, *args):
299 """Select the geometrical entities of this Sketch on which
300 the result Face must be built.
302 When no entity is given, the face is based on all existing
303 geometry of this Sketch.
306 self._selection = modelAPI_ResultConstruction(
307 self._feature.firstResult()
310 self._selection = args[0].shape()
312 raise Exception("not yet implemented")
313 # TODO: simple version now, should be a list of selected faces
314 return [Selection(self.result(), self.buildShape())]
316 def buildShape(self):
317 """Build the result Shape of this Sketch according to the
318 selected geometrical entities."""
319 o = self._origin.pnt()
320 dx = self._dir_x.dir()
323 # The faces are kept otherwise they are destroyed at exit
325 GeomAlgoAPI_SketchBuilder.createFaces(o, dx, n, self._selection, faces)
326 # TODO: Deal with several faces
330 """Returns the result data of this Feature."""
331 return self._feature.firstResult()