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
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 setFillet(self, line_1, line_2, radius):
192 """Set a fillet constraint between the 3 given lines with the given
194 constraint = self._feature.addFeature("SketchConstraintFillet")
195 constraint.data().refattr("ConstraintEntityA").setObject(line_1)
196 constraint.data().refattr("ConstraintEntityB").setObject(line_2)
197 constraint.data().real("ConstraintValue").setValue(radius)
198 self._feature.execute()
201 #-------------------------------------------------------------
203 # Edition of Dimensional Constraints
205 #-------------------------------------------------------------
207 def setValue(self, constraint, value):
208 """Modify the value of the given dimensional constraint."""
209 constraint.data().real("ConstraintValue").setValue(value)
211 #-------------------------------------------------------------
213 # Macro functions combining geometry creation and constraints
215 #-------------------------------------------------------------
217 def addPolyline(self, *coords):
218 """Add a poly-line to this Sketch.
220 The end of consecutive segments are defined as coincident.
225 line_1 = self.addLine(c0, c1)
226 polyline.append(line_1)
227 # Adding and connecting next lines
228 for c2 in coords[2:]:
229 line_2 = self.addLine(c1, c2)
230 self.setCoincident(line_1.endPointData(), line_2.startPointData())
231 polyline.append(line_2)
236 def addPolygon(self, *coords):
237 """Add a polygon to this Sketch.
239 The end of consecutive segments are defined as coincident.
241 pg = self.addPolyline(*coords)
242 # Closing the poly-line supposed being defined by at least 3 points
244 cn = coords[len(coords) - 1]
245 ln = self.addLine(cn, c0)
247 pg[len(coords) - 2].endPointData(), ln.startPointData()
250 ln.endPointData(), pg[0].startPointData()
255 #-------------------------------------------------------------
259 #-------------------------------------------------------------
261 def selectFace(self, *args):
262 """Select the geometrical entities of this Sketch on which
263 the result Face must be built.
265 When no entity is given, the face is based on all existing
266 geometry of this Sketch.
269 self._selection = modelAPI_ResultConstruction(
270 self._feature.firstResult()).shape()
272 self._selection = args[0].shape()
274 raise Exception("not yet implemented")
277 def buildShape(self):
278 """Build the result Shape of this Sketch according to the
279 selected geometrical entities."""
280 o = geomDataAPI_Point( self._feature.data().attribute("Origin") ).pnt()
281 dx = geomDataAPI_Dir( self._feature.data().attribute("DirX") ).dir()
282 n = geomDataAPI_Dir( self._feature.data().attribute("Norm") ).dir()
284 # The faces are kept otherwise they are destroyed at exit
286 GeomAlgoAPI_SketchBuilder.createFaces(o, dx, n, self._selection, faces)
287 #TODO: Deal with several faces
291 """Returns the result data of this Feature."""
292 return self._feature.firstResult()