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
13 from model.roots import Interface
15 def addSketch(doc, plane):
16 """Add a Sketch feature to the Part or PartSet and return an interface
19 A Sketch object is instanciated with a feature as input parameter
20 it provides an interface for manipulation of the feature data.
21 :return: interface on the feature
23 feature = featureToCompositeFeature(doc.addFeature("Sketch"))
24 return Sketch(feature, plane)
26 class Sketch(Interface):
27 """Interface on a Sketch feature."""
28 def __init__(self, feature, plane):
29 """Initialize a 2D Sketch on the given plane.
31 The plane can be defined either by:
32 - a 3D axis system (geom.Ax3),
33 - an existing face identified by its topological name.
35 Interface.__init__(self, feature)
36 assert(self._feature.getKind() == "Sketch")
38 # Entities used for building the result shape
39 self._selection = None
40 # self.resultype ="Face" # Type of Sketch result
41 if isinstance(plane, str):
42 self.__sketchOnFace(plane)
44 self.__sketchOnPlane(plane)
46 def __sketchOnPlane(self, plane):
47 """Create the sketch on a plane."""
48 origin = plane.location()
49 normal = plane.direction()
50 x_direction = plane.xDirection()
52 self._feature.data().attribute("Origin")
53 ).setValue(origin.x(), origin.y(), origin.z())
55 self._feature.data().attribute("DirX")
56 ).setValue(x_direction.x(), x_direction.y(), x_direction.z())
58 self._feature.data().attribute("Norm")
59 ).setValue(normal.x(), normal.y(), normal.z() )
61 def __sketchOnFace(self, name):
62 """Initialize the sketch on a face given by its name."""
63 self._feature.data().selection("External").selectSubShape("FACE", name)
65 #-------------------------------------------------------------
67 # Creation of Geometries
69 #-------------------------------------------------------------
71 def addPoint(self, *args):
72 """Add a point to this Sketch."""
73 point_feature = self._feature.addFeature("SketchPoint")
74 return Point(point_feature, *args)
76 def addLine(self, *args):
77 """Add a line to this Sketch."""
78 line_feature = self._feature.addFeature("SketchLine")
79 line_interface = Line(line_feature, *args)
80 # if the line is created by name add a rigid constraint
82 if len(args) == 1 and isinstance(args[0], str):
83 constraint = sketch.addFeature("SketchConstraintRigid")
84 constraint.refattr("ConstraintEntityA").setObject(
85 line_feature.firstResult()
89 def addCircle(self, *args):
90 """Add a circle to this Sketch."""
91 circle_feature = self._feature.addFeature("SketchCircle")
92 return Circle(circle_feature, *args)
94 def addArc(self, *args):
95 """Add an arc to this Sketch."""
96 arc_feature = self._feature.addFeature("SketchArc")
97 return Arc(arc_feature, *args)
99 #-------------------------------------------------------------
101 # Creation of Geometrical and Dimensional Constraints
103 #-------------------------------------------------------------
105 def setCoincident(self, p1, p2):
106 """Set coincident the two given points and add the corresponding
107 constraint to this Sketch."""
108 constraint = self._feature.addFeature("SketchConstraintCoincidence")
109 constraint.data().refattr("ConstraintEntityA").setAttr(p1)
110 constraint.data().refattr("ConstraintEntityB").setAttr(p2)
113 def setParallel(self, l1, l2):
114 """Set parallel the two given lines and add the corresponding
115 constraint to this Sketch."""
116 constraint = self._feature.addFeature("SketchConstraintParallel")
117 constraint.data().refattr("ConstraintEntityA").setObject(l1)
118 constraint.data().refattr("ConstraintEntityB").setObject(l2)
121 def setPerpendicular(self, l1, l2):
122 """Set perpendicular the two given lines and add the corresponding
123 constraint to this Sketch."""
124 constraint = self._feature.addFeature("SketchConstraintPerpendicular")
125 constraint.data().refattr("ConstraintEntityA").setObject(l1)
126 constraint.data().refattr("ConstraintEntityB").setObject(l2)
129 def setHorizontal(self, line):
130 """Set horizontal the given line and add the corresponding
131 constraint to this Sketch."""
132 constraint = self._feature.addFeature("SketchConstraintHorizontal")
133 constraint.data().refattr("ConstraintEntityA").setObject(line)
136 def setVertical(self, line):
137 """Set vertical the given line and add the corresponding
138 constraint to this Sketch."""
139 constraint = self._feature.addFeature("SketchConstraintVertical")
140 constraint.data().refattr("ConstraintEntityA").setObject(line)
143 def setDistance(self, point, line, length):
144 """Set the distance between the given point and line, and add
145 the corresponding constraint to this Sketch."""
146 constraint = self._feature.addFeature("SketchConstraintDistance")
147 if isinstance(line, str):
148 # Add the edge identified by the given topological name
150 line = self.addLine(line).result()
151 constraint.data().refattr("ConstraintEntityA").setAttr(point)
152 constraint.data().refattr("ConstraintEntityB").setObject(line)
153 constraint.data().real("ConstraintValue").setValue(length)
154 self._feature.execute()
157 def setLength(self, line, length):
158 """Set the length of the given line and add the corresponding
159 constraint to this Sketch."""
160 constraint = self._feature.addFeature("SketchConstraintLength")
161 constraint.data().refattr("ConstraintEntityA").setObject(line)
162 constraint.data().real("ConstraintValue").setValue(length)
163 self._feature.execute()
166 def setRadius(self, circle, radius):
167 """Set the radius of the given circle and add the corresponding
168 constraint to this Sketch."""
169 constraint = self._feature.addFeature("SketchConstraintRadius")
170 constraint.data().refattr("ConstraintEntityA").setObject(circle)
171 constraint.data().real("ConstraintValue").setValue(radius)
174 def setEqual(self, object_1, object_2):
175 """Set the radii of two circles or the length of two lines equal.
177 The corresponding constraint is added to the sketch"""
178 constraint = self._feature.addFeature("SketchConstraintEqual")
179 constraint.data().refattr("ConstraintEntityA").setObject(object_1)
180 constraint.data().refattr("ConstraintEntityB").setObject(object_2)
181 self._feature.execute()
184 def setAngle(self, line_1, line_2, angle):
185 """Set the angle between the given 2 lines and add the corresponding
186 constraint to the sketch."""
187 constraint = self._feature.addFeature("SketchConstraintAngle")
188 constraint.data().refattr("ConstraintEntityA").setObject(line_1)
189 constraint.data().refattr("ConstraintEntityB").setObject(line_2)
190 constraint.data().real("ConstraintValue").setValue(angle)
191 self._feature.execute()
194 def setTangent(self, object_1, object_2):
195 """Set a tangential continuity between two objects
196 at their coincidence point."""
197 constraint = self._feature.addFeature("SketchConstraintTangent")
198 constraint.data().refattr("ConstraintEntityA").setObject(object_1)
199 constraint.data().refattr("ConstraintEntityB").setObject(object_2)
200 self._feature.execute()
203 def setFillet(self, line_1, line_2, radius):
204 """Set a fillet constraint between the 3 given lines with the given
206 constraint = self._feature.addFeature("SketchConstraintFillet")
207 constraint.data().refattr("ConstraintEntityA").setObject(line_1)
208 constraint.data().refattr("ConstraintEntityB").setObject(line_2)
209 constraint.data().real("ConstraintValue").setValue(radius)
210 self._feature.execute()
213 #-------------------------------------------------------------
215 # Edition of Dimensional Constraints
217 #-------------------------------------------------------------
219 def setValue(self, constraint, value):
220 """Modify the value of the given dimensional constraint."""
221 constraint.data().real("ConstraintValue").setValue(value)
223 #-------------------------------------------------------------
225 # Macro functions combining geometry creation and constraints
227 #-------------------------------------------------------------
229 def addPolyline(self, *coords):
230 """Add a poly-line to this Sketch.
232 The end of consecutive segments are defined as coincident.
237 line_1 = self.addLine(c0, c1)
238 polyline.append(line_1)
239 # Adding and connecting next lines
240 for c2 in coords[2:]:
241 line_2 = self.addLine(c1, c2)
242 self.setCoincident(line_1.endPointData(), line_2.startPointData())
243 polyline.append(line_2)
248 def addPolygon(self, *coords):
249 """Add a polygon to this Sketch.
251 The end of consecutive segments are defined as coincident.
253 pg = self.addPolyline(*coords)
254 # Closing the poly-line supposed being defined by at least 3 points
256 cn = coords[len(coords) - 1]
257 ln = self.addLine(cn, c0)
259 pg[len(coords) - 2].endPointData(), ln.startPointData()
262 ln.endPointData(), pg[0].startPointData()
267 #-------------------------------------------------------------
271 #-------------------------------------------------------------
273 def selectFace(self, *args):
274 """Select the geometrical entities of this Sketch on which
275 the result Face must be built.
277 When no entity is given, the face is based on all existing
278 geometry of this Sketch.
281 self._selection = modelAPI_ResultConstruction(
282 self._feature.firstResult()).shape()
284 self._selection = args[0].shape()
286 raise Exception("not yet implemented")
289 def buildShape(self):
290 """Build the result Shape of this Sketch according to the
291 selected geometrical entities."""
292 o = geomDataAPI_Point( self._feature.data().attribute("Origin") ).pnt()
293 dx = geomDataAPI_Dir( self._feature.data().attribute("DirX") ).dir()
294 n = geomDataAPI_Dir( self._feature.data().attribute("Norm") ).dir()
296 # The faces are kept otherwise they are destroyed at exit
298 GeomAlgoAPI_SketchBuilder.createFaces(o, dx, n, self._selection, faces)
299 #TODO: Deal with several faces
303 """Returns the result data of this Feature."""
304 return self._feature.firstResult()