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)
72 def __sketchOnPlane(self, plane):
73 """Create the sketch on a plane."""
74 origin = plane.location()
75 normal = plane.direction()
76 x_direction = plane.xDirection()
77 self._origin.setValue(origin.x(), origin.y(), origin.z())
78 self._norm.setValue(normal.x(), normal.y(), normal.z())
79 self._dir_x.setValue(x_direction.x(), x_direction.y(), x_direction.z())
81 def __sketchOnFace(self, name):
82 """Initialize the sketch on a face given by its name."""
83 self._external.selectSubShape("FACE", name)
85 #-------------------------------------------------------------
87 # Creation of Geometries
89 #-------------------------------------------------------------
91 def addPoint(self, *args):
92 """Add a point to this Sketch."""
93 point_feature = self._feature.addFeature("SketchPoint")
94 return Point(point_feature, *args)
96 def addLine(self, *args):
97 """Add a line to this Sketch."""
98 line_feature = self._feature.addFeature("SketchLine")
99 line_interface = Line(line_feature, *args)
100 # if the line is created by name add a rigid constraint
101 # to the created line
102 if len(args) == 1 and isinstance(args[0], str):
103 constraint = self._feature.addFeature("SketchConstraintRigid")
104 constraint.refattr("ConstraintEntityA").setObject(
105 line_feature.firstResult()
107 return line_interface
109 def addCircle(self, *args):
110 """Add a circle to this Sketch."""
111 circle_feature = self._feature.addFeature("SketchCircle")
112 return Circle(circle_feature, *args)
114 def addArc(self, *args):
115 """Add an arc to this Sketch."""
116 arc_feature = self._feature.addFeature("SketchArc")
117 return Arc(arc_feature, *args)
119 #-------------------------------------------------------------
121 # Creation of Geometrical and Dimensional Constraints
123 #-------------------------------------------------------------
125 def setCoincident(self, p1, p2):
126 """Set coincident the two given points and add the corresponding
127 constraint to this Sketch."""
129 constraint = self._feature.addFeature("SketchConstraintCoincidence")
130 constraint.data().refattr("ConstraintEntityA").setAttr(p1)
131 constraint.data().refattr("ConstraintEntityB").setAttr(p2)
135 def setParallel(self, l1, l2):
136 """Set parallel the two given lines and add the corresponding
137 constraint to this Sketch."""
139 constraint = self._feature.addFeature("SketchConstraintParallel")
140 constraint.data().refattr("ConstraintEntityA").setObject(l1)
141 constraint.data().refattr("ConstraintEntityB").setObject(l2)
145 def setPerpendicular(self, l1, l2):
146 """Set perpendicular the two given lines and add the corresponding
147 constraint to this Sketch."""
149 constraint = self._feature.addFeature("SketchConstraintPerpendicular")
150 constraint.data().refattr("ConstraintEntityA").setObject(l1)
151 constraint.data().refattr("ConstraintEntityB").setObject(l2)
155 def setHorizontal(self, line):
156 """Set horizontal the given line and add the corresponding
157 constraint to this Sketch."""
158 constraint = self._feature.addFeature("SketchConstraintHorizontal")
159 constraint.data().refattr("ConstraintEntityA").setObject(line)
163 def setVertical(self, line):
164 """Set vertical the given line and add the corresponding
165 constraint to this Sketch."""
166 constraint = self._feature.addFeature("SketchConstraintVertical")
167 constraint.data().refattr("ConstraintEntityA").setObject(line)
171 def setDistance(self, point, line, length):
172 """Set the distance between the given point and line, and add
173 the corresponding constraint to this Sketch."""
174 assert(point and line)
175 constraint = self._feature.addFeature("SketchConstraintDistance")
176 if isinstance(line, basestring):
177 # Add the edge identified by the given topological name
179 line = self.addLine(line).result()
181 constraint.data().refattr("ConstraintEntityA").setAttr(point)
182 constraint.data().refattr("ConstraintEntityB").setObject(line)
183 constraint.data().real("ConstraintValue").setValue(length)
187 def setLength(self, line, length):
188 """Set the length of the given line and add the corresponding
189 constraint to this Sketch."""
191 constraint = self._feature.addFeature("SketchConstraintLength")
192 constraint.data().refattr("ConstraintEntityA").setObject(line)
193 constraint.data().real("ConstraintValue").setValue(length)
197 def setRadius(self, circle, radius):
198 """Set the radius of the given circle and add the corresponding
199 constraint to this Sketch."""
200 constraint = self._feature.addFeature("SketchConstraintRadius")
201 constraint.data().refattr("ConstraintEntityA").setObject(circle)
202 constraint.data().real("ConstraintValue").setValue(radius)
206 def setEqual(self, object_1, object_2):
207 """Set the radii of two circles or the length of two lines equal.
209 The corresponding constraint is added to the sketch"""
210 constraint = self._feature.addFeature("SketchConstraintEqual")
211 constraint.data().refattr("ConstraintEntityA").setObject(object_1)
212 constraint.data().refattr("ConstraintEntityB").setObject(object_2)
216 def setAngle(self, line_1, line_2, angle):
217 """Set the angle between the given 2 lines and add the corresponding
218 constraint to the sketch."""
219 constraint = self._feature.addFeature("SketchConstraintAngle")
220 constraint.data().refattr("ConstraintEntityA").setObject(line_1)
221 constraint.data().refattr("ConstraintEntityB").setObject(line_2)
222 constraint.data().real("ConstraintValue").setValue(angle)
226 def setTangent(self, object_1, object_2):
227 """Set a tangential continuity between two objects
228 at their coincidence point."""
229 constraint = self._feature.addFeature("SketchConstraintTangent")
230 constraint.data().refattr("ConstraintEntityA").setObject(object_1)
231 constraint.data().refattr("ConstraintEntityB").setObject(object_2)
235 def setFillet(self, line_1, line_2, radius):
236 """Set a fillet constraint between the 3 given lines with the given
238 constraint = self._feature.addFeature("SketchConstraintFillet")
239 constraint.data().refattr("ConstraintEntityA").setObject(line_1)
240 constraint.data().refattr("ConstraintEntityB").setObject(line_2)
241 constraint.data().real("ConstraintValue").setValue(radius)
245 #-------------------------------------------------------------
247 # Edition of Dimensional Constraints
249 #-------------------------------------------------------------
251 def setValue(self, constraint, value):
252 """Modify the value of the given dimensional constraint."""
253 constraint.data().real("ConstraintValue").setValue(value)
255 #-------------------------------------------------------------
257 # Macro functions combining geometry creation and constraints
259 #-------------------------------------------------------------
261 def addPolyline(self, *coords):
262 """Add a poly-line to this Sketch.
264 The end of consecutive segments are defined as coincident.
269 line_1 = self.addLine(c0, c1)
270 polyline.append(line_1)
271 # Adding and connecting next lines
272 for c2 in coords[2:]:
273 line_2 = self.addLine(c1, c2)
274 self.setCoincident(line_1.endPointData(), line_2.startPointData())
275 polyline.append(line_2)
280 def addPolygon(self, *coords):
281 """Add a polygon to this Sketch.
283 The end of consecutive segments are defined as coincident.
285 pg = self.addPolyline(*coords)
286 # Closing the poly-line supposed being defined by at least 3 points
288 cn = coords[len(coords) - 1]
289 ln = self.addLine(cn, c0)
291 pg[len(coords) - 2].endPointData(), ln.startPointData()
294 ln.endPointData(), pg[0].startPointData()
299 #-------------------------------------------------------------
303 #-------------------------------------------------------------
305 def selectFace(self, *args):
306 """Select the geometrical entities of this Sketch on which
307 the result Face must be built.
309 When no entity is given, the face is based on all existing
310 geometry of this Sketch.
313 self._selection = modelAPI_ResultConstruction(
314 self._feature.firstResult()
317 self._selection = args[0].shape()
319 raise Exception("not yet implemented")
320 # TODO: simple version now, should be a list of selected faces
321 return [Selection(self.result(), self.buildShape())]
323 def buildShape(self):
324 """Build the result Shape of this Sketch according to the
325 selected geometrical entities."""
326 o = self._origin.pnt()
327 dx = self._dir_x.dir()
330 # The faces are kept otherwise they are destroyed at exit
332 GeomAlgoAPI_SketchBuilder.createFaces(o, dx, n, self._selection, faces)
333 # TODO: Deal with several faces
337 """Returns the result data of this Feature."""
338 return self._feature.firstResult()