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
9 from model.sketcher.point import Point
10 from model.sketcher.line import Line
11 from model.sketcher.circle import Circle
12 from model.sketcher.arc import Arc
14 def addSketch(doc, plane):
15 """Add a Sketch feature to the Part or PartSet and return an interface
18 A Sketch object is instanciated with a feature as input parameter
19 it provides an interface for manipulation of the feature data.
20 :return: interface on the feature
22 feature = featureToCompositeFeature(doc.addFeature("Sketch"))
23 return Sketch(feature, plane)
26 """Interface on a Sketch feature."""
27 def __init__(self, feature, plane):
28 """Initialize a 2D Sketch on the given plane.
30 The plane can be defined either by:
31 - a 3D axis system (geom.Ax3),
32 - an existing face identified by its topological name.
34 self._feature = feature
35 # Entities used for building the result shape
36 self._selection = None
37 # self.resultype ="Face" # Type of Sketch result
38 if isinstance(plane, str):
39 self.__sketchOnFace(plane)
41 self.__sketchOnPlane(plane)
43 def __sketchOnPlane(self, plane):
44 """Create the sketch on a plane."""
45 origin = plane.location()
46 normal = plane.direction()
47 x_direction = plane.xDirection()
49 self._feature.data().attribute("Origin")
50 ).setValue(origin.x(), origin.y(), origin.z())
52 self._feature.data().attribute("DirX")
53 ).setValue(x_direction.x(), x_direction.y(), x_direction.z())
55 self._feature.data().attribute("Norm")
56 ).setValue(normal.x(), normal.y(), normal.z() )
58 def __sketchOnFace(self, name):
59 """Initialize the sketch on a face given by its name."""
60 self._feature.data().selection("External").selectSubShape("FACE", name)
62 #-------------------------------------------------------------
64 # Creation of Geometries
66 #-------------------------------------------------------------
68 def addPoint(self, *args):
69 """Add a point to this Sketch."""
70 point_feature = self._feature.addFeature("SketchPoint")
71 return Point(point_feature, *args)
73 def addLine(self, *args):
74 """Add a line to this Sketch."""
75 line_feature = self._feature.addFeature("SketchLine")
76 line_interface = Line(line_feature, *args)
77 # if the line is created by name add a rigid constraint
79 if len(args) == 1 and isinstance(args[0], str):
80 constraint = sketch.addFeature("SketchConstraintRigid")
81 constraint.refattr("ConstraintEntityA").setObject(
82 line_feature.firstResult()
86 def addCircle(self, *args):
87 """Add a circle to this Sketch."""
88 circle_feature = self._feature.addFeature("SketchCircle")
89 return Circle(circle_feature, *args)
91 def addArc(self, *args):
92 """Add an arc to this Sketch."""
93 arc_feature = self._feature.addFeature("SketchArc")
94 return Arc(arc_feature, *args)
96 #-------------------------------------------------------------
98 # Creation of Geometrical and Dimensional Constraints
100 #-------------------------------------------------------------
102 def setCoincident(self, p1, p2):
103 """Set coincident the two given points and add the corresponding
104 constraint to this Sketch."""
105 constraint = self._feature.addFeature("SketchConstraintCoincidence")
106 constraint.data().refattr("ConstraintEntityA").setAttr(p1)
107 constraint.data().refattr("ConstraintEntityB").setAttr(p2)
110 def setParallel(self, l1, l2):
111 """Set parallel the two given lines and add the corresponding
112 constraint to this Sketch."""
113 constraint = self._feature.addFeature("SketchConstraintParallel")
114 constraint.data().refattr("ConstraintEntityA").setObject(l1)
115 constraint.data().refattr("ConstraintEntityB").setObject(l2)
118 def setPerpendicular(self, l1, l2):
119 """Set perpendicular the two given lines and add the corresponding
120 constraint to this Sketch."""
121 constraint = self._feature.addFeature("SketchConstraintPerpendicular")
122 constraint.data().refattr("ConstraintEntityA").setObject(l1)
123 constraint.data().refattr("ConstraintEntityB").setObject(l2)
126 def setHorizontal(self, line):
127 """Set horizontal the given line and add the corresponding
128 constraint to this Sketch."""
129 constraint = self._feature.addFeature("SketchConstraintHorizontal")
130 constraint.data().refattr("ConstraintEntityA").setObject(line)
133 def setVertical(self, line):
134 """Set vertical the given line and add the corresponding
135 constraint to this Sketch."""
136 constraint = self._feature.addFeature("SketchConstraintVertical")
137 constraint.data().refattr("ConstraintEntityA").setObject(line)
140 def setDistance(self, point, line, length):
141 """Set the distance between the given point and line, and add
142 the corresponding constraint to this Sketch."""
143 constraint = self._feature.addFeature("SketchConstraintDistance")
144 if isinstance(line, str):
145 # Add the edge identified by the given topological name
147 line = self.addLine(line).result()
148 constraint.data().refattr("ConstraintEntityA").setAttr(point)
149 constraint.data().refattr("ConstraintEntityB").setObject(line)
150 constraint.data().real("ConstraintValue").setValue(length)
151 self._feature.execute()
154 def setLength(self, line, length):
155 """Set the length of the given line and add the corresponding
156 constraint to this Sketch."""
157 constraint = self._feature.addFeature("SketchConstraintLength")
158 constraint.data().refattr("ConstraintEntityA").setObject(line)
159 constraint.data().real("ConstraintValue").setValue(length)
160 self._feature.execute()
163 def setRadius(self, circle, radius):
164 """Set the radius of the given circle and add the corresponding
165 constraint to this Sketch."""
166 constraint = self._feature.addFeature("SketchConstraintRadius")
167 constraint.data().refattr("ConstraintEntityA").setObject(circle)
168 constraint.data().real("ConstraintValue").setValue(radius)
171 def setEqual(self, object_1, object_2):
172 """Set the radii of two circles or the length of two lines equal.
174 The corresponding constraint is added to the sketch"""
175 constraint = self._feature.addFeature("SketchConstraintEqual")
176 constraint.data().refattr("ConstraintEntityA").setObject(object_1)
177 constraint.data().refattr("ConstraintEntityB").setObject(object_2)
178 self._feature.execute()
181 def setAngle(self, line_1, line_2, angle):
182 """Set the angle between the given 2 lines and add the corresponding
183 constraint to the sketch."""
184 constraint = self._feature.addFeature("SketchConstraintAngle")
185 constraint.data().refattr("ConstraintEntityA").setObject(line_1)
186 constraint.data().refattr("ConstraintEntityB").setObject(line_2)
187 constraint.data().real("ConstraintValue").setValue(angle)
188 self._feature.execute()
191 def setTangent(self, object_1, object_2):
192 """Set a tangential continuity between two objects
193 at their coincidence point."""
194 constraint = self._feature.addFeature("SketchConstraintTangent")
195 constraint.data().refattr("ConstraintEntityA").setObject(object_1)
196 constraint.data().refattr("ConstraintEntityB").setObject(object_2)
197 self._feature.execute()
200 def setFillet(self, line_1, line_2, radius):
201 """Set a fillet constraint between the 3 given lines with the given
203 constraint = self._feature.addFeature("SketchConstraintFillet")
204 constraint.data().refattr("ConstraintEntityA").setObject(line_1)
205 constraint.data().refattr("ConstraintEntityB").setObject(line_2)
206 constraint.data().real("ConstraintValue").setValue(radius)
207 self._feature.execute()
210 #-------------------------------------------------------------
212 # Edition of Dimensional Constraints
214 #-------------------------------------------------------------
216 def setValue(self, constraint, value):
217 """Modify the value of the given dimensional constraint."""
218 constraint.data().real("ConstraintValue").setValue(value)
220 #-------------------------------------------------------------
222 # Macro functions combining geometry creation and constraints
224 #-------------------------------------------------------------
226 def addPolyline(self, *coords):
227 """Add a poly-line to this Sketch.
229 The end of consecutive segments are defined as coincident.
234 line_1 = self.addLine(c0, c1)
235 polyline.append(line_1)
236 # Adding and connecting next lines
237 for c2 in coords[2:]:
238 line_2 = self.addLine(c1, c2)
239 self.setCoincident(line_1.endPointData(), line_2.startPointData())
240 polyline.append(line_2)
245 def addPolygon(self, *coords):
246 """Add a polygon to this Sketch.
248 The end of consecutive segments are defined as coincident.
250 pg = self.addPolyline(*coords)
251 # Closing the poly-line supposed being defined by at least 3 points
253 cn = coords[len(coords) - 1]
254 ln = self.addLine(cn, c0)
256 pg[len(coords) - 2].endPointData(), ln.startPointData()
259 ln.endPointData(), pg[0].startPointData()
264 #-------------------------------------------------------------
268 #-------------------------------------------------------------
270 def selectFace(self, *args):
271 """Select the geometrical entities of this Sketch on which
272 the result Face must be built.
274 When no entity is given, the face is based on all existing
275 geometry of this Sketch.
278 self._selection = modelAPI_ResultConstruction(
279 self._feature.firstResult()).shape()
281 self._selection = args[0].shape()
283 raise Exception("not yet implemented")
286 def buildShape(self):
287 """Build the result Shape of this Sketch according to the
288 selected geometrical entities."""
289 o = geomDataAPI_Point( self._feature.data().attribute("Origin") ).pnt()
290 dx = geomDataAPI_Dir( self._feature.data().attribute("DirX") ).dir()
291 n = geomDataAPI_Dir( self._feature.data().attribute("Norm") ).dir()
293 # The faces are kept otherwise they are destroyed at exit
295 GeomAlgoAPI_SketchBuilder.createFaces(o, dx, n, self._selection, faces)
296 #TODO: Deal with several faces
300 """Returns the result data of this Feature."""
301 return self._feature.firstResult()