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, plane):
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 # Entities used for building the result shape
42 self._selection = None
43 # self.resultype ="Face" # Type of Sketch result
44 if isinstance(plane, str):
45 self.__sketchOnFace(plane)
47 self.__sketchOnPlane(plane)
49 def __sketchOnPlane(self, plane):
50 """Create the sketch on a plane."""
51 origin = plane.location()
52 normal = plane.direction()
53 x_direction = plane.xDirection()
55 self._feature.data().attribute("Origin")
56 ).setValue(origin.x(), origin.y(), origin.z())
58 self._feature.data().attribute("DirX")
59 ).setValue(x_direction.x(), x_direction.y(), x_direction.z())
61 self._feature.data().attribute("Norm")
62 ).setValue(normal.x(), normal.y(), normal.z() )
64 def __sketchOnFace(self, name):
65 """Initialize the sketch on a face given by its name."""
66 self._feature.data().selection("External").selectSubShape("FACE", name)
68 #-------------------------------------------------------------
70 # Creation of Geometries
72 #-------------------------------------------------------------
74 def addPoint(self, *args):
75 """Add a point to this Sketch."""
76 point_feature = self._feature.addFeature("SketchPoint")
77 return Point(point_feature, *args)
79 def addLine(self, *args):
80 """Add a line to this Sketch."""
81 line_feature = self._feature.addFeature("SketchLine")
82 line_interface = Line(line_feature, *args)
83 # if the line is created by name add a rigid constraint
85 if len(args) == 1 and isinstance(args[0], str):
86 constraint = sketch.addFeature("SketchConstraintRigid")
87 constraint.refattr("ConstraintEntityA").setObject(
88 line_feature.firstResult()
92 def addCircle(self, *args):
93 """Add a circle to this Sketch."""
94 circle_feature = self._feature.addFeature("SketchCircle")
95 return Circle(circle_feature, *args)
97 def addArc(self, *args):
98 """Add an arc to this Sketch."""
99 arc_feature = self._feature.addFeature("SketchArc")
100 return Arc(arc_feature, *args)
102 #-------------------------------------------------------------
104 # Creation of Geometrical and Dimensional Constraints
106 #-------------------------------------------------------------
108 def setCoincident(self, p1, p2):
109 """Set coincident the two given points and add the corresponding
110 constraint to this Sketch."""
111 constraint = self._feature.addFeature("SketchConstraintCoincidence")
112 constraint.data().refattr("ConstraintEntityA").setAttr(p1)
113 constraint.data().refattr("ConstraintEntityB").setAttr(p2)
116 def setParallel(self, l1, l2):
117 """Set parallel the two given lines and add the corresponding
118 constraint to this Sketch."""
119 constraint = self._feature.addFeature("SketchConstraintParallel")
120 constraint.data().refattr("ConstraintEntityA").setObject(l1)
121 constraint.data().refattr("ConstraintEntityB").setObject(l2)
124 def setPerpendicular(self, l1, l2):
125 """Set perpendicular the two given lines and add the corresponding
126 constraint to this Sketch."""
127 constraint = self._feature.addFeature("SketchConstraintPerpendicular")
128 constraint.data().refattr("ConstraintEntityA").setObject(l1)
129 constraint.data().refattr("ConstraintEntityB").setObject(l2)
132 def setHorizontal(self, line):
133 """Set horizontal the given line and add the corresponding
134 constraint to this Sketch."""
135 constraint = self._feature.addFeature("SketchConstraintHorizontal")
136 constraint.data().refattr("ConstraintEntityA").setObject(line)
139 def setVertical(self, line):
140 """Set vertical the given line and add the corresponding
141 constraint to this Sketch."""
142 constraint = self._feature.addFeature("SketchConstraintVertical")
143 constraint.data().refattr("ConstraintEntityA").setObject(line)
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
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()
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()
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)
177 def setEqual(self, object_1, object_2):
178 """Set the radii of two circles or the length of two lines equal.
180 The corresponding constraint is added to the sketch"""
181 constraint = self._feature.addFeature("SketchConstraintEqual")
182 constraint.data().refattr("ConstraintEntityA").setObject(object_1)
183 constraint.data().refattr("ConstraintEntityB").setObject(object_2)
184 self._feature.execute()
187 def setAngle(self, line_1, line_2, angle):
188 """Set the angle between the given 2 lines and add the corresponding
189 constraint to the sketch."""
190 constraint = self._feature.addFeature("SketchConstraintAngle")
191 constraint.data().refattr("ConstraintEntityA").setObject(line_1)
192 constraint.data().refattr("ConstraintEntityB").setObject(line_2)
193 constraint.data().real("ConstraintValue").setValue(angle)
194 self._feature.execute()
197 def setTangent(self, object_1, object_2):
198 """Set a tangential continuity between two objects
199 at their coincidence point."""
200 constraint = self._feature.addFeature("SketchConstraintTangent")
201 constraint.data().refattr("ConstraintEntityA").setObject(object_1)
202 constraint.data().refattr("ConstraintEntityB").setObject(object_2)
203 self._feature.execute()
206 def setFillet(self, line_1, line_2, radius):
207 """Set a fillet constraint between the 3 given lines with the given
209 constraint = self._feature.addFeature("SketchConstraintFillet")
210 constraint.data().refattr("ConstraintEntityA").setObject(line_1)
211 constraint.data().refattr("ConstraintEntityB").setObject(line_2)
212 constraint.data().real("ConstraintValue").setValue(radius)
213 self._feature.execute()
216 #-------------------------------------------------------------
218 # Edition of Dimensional Constraints
220 #-------------------------------------------------------------
222 def setValue(self, constraint, value):
223 """Modify the value of the given dimensional constraint."""
224 constraint.data().real("ConstraintValue").setValue(value)
226 #-------------------------------------------------------------
228 # Macro functions combining geometry creation and constraints
230 #-------------------------------------------------------------
232 def addPolyline(self, *coords):
233 """Add a poly-line to this Sketch.
235 The end of consecutive segments are defined as coincident.
240 line_1 = self.addLine(c0, c1)
241 polyline.append(line_1)
242 # Adding and connecting next lines
243 for c2 in coords[2:]:
244 line_2 = self.addLine(c1, c2)
245 self.setCoincident(line_1.endPointData(), line_2.startPointData())
246 polyline.append(line_2)
251 def addPolygon(self, *coords):
252 """Add a polygon to this Sketch.
254 The end of consecutive segments are defined as coincident.
256 pg = self.addPolyline(*coords)
257 # Closing the poly-line supposed being defined by at least 3 points
259 cn = coords[len(coords) - 1]
260 ln = self.addLine(cn, c0)
262 pg[len(coords) - 2].endPointData(), ln.startPointData()
265 ln.endPointData(), pg[0].startPointData()
270 #-------------------------------------------------------------
274 #-------------------------------------------------------------
276 def selectFace(self, *args):
277 """Select the geometrical entities of this Sketch on which
278 the result Face must be built.
280 When no entity is given, the face is based on all existing
281 geometry of this Sketch.
284 self._selection = modelAPI_ResultConstruction(
285 self._feature.firstResult()).shape()
287 self._selection = args[0].shape()
288 return Selection(self.result(), self.buildShape())
290 raise Exception("not yet implemented")
293 def buildShape(self):
294 """Build the result Shape of this Sketch according to the
295 selected geometrical entities."""
296 o = geomDataAPI_Point( self._feature.data().attribute("Origin") ).pnt()
297 dx = geomDataAPI_Dir( self._feature.data().attribute("DirX") ).dir()
298 n = geomDataAPI_Dir( self._feature.data().attribute("Norm") ).dir()
300 # The faces are kept otherwise they are destroyed at exit
302 GeomAlgoAPI_SketchBuilder.createFaces(o, dx, n, self._selection, faces)
303 #TODO: Deal with several faces
307 """Returns the result data of this Feature."""
308 return self._feature.firstResult()