-"""Sketch Feature Interface
-Author: Daniel Brunier-Coulin with contribution by Mikhail Ponikarov
-Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+# Author: Daniel Brunier-Coulin with contribution by Mikhail Ponikarov
+# finalized by Renaud Nedelec and Sergey Pokhodenko
+# Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+"""Sketcher interface.
+This interface allows to add a sketch
+in a part or partset.
+The created sketch object provides all the needed methods
+for sketch modification and constraint edition.
+
+Example of code:
+
+.. doctest::
+
+ >>> import model
+ >>> model.begin()
+ >>> partset = model.moduleDocument()
+ >>> part = model.addPart(partset).document()
+ >>> plane = model.defaultPlane("XOY")
+ >>> sketch = model.addSketch(part, plane)
+ >>> line = sketch.addLine(0, 0, 0, 1)
+ >>> line.endPoint().x()
+ 0.0
+ >>> line.endPoint().y()
+ 1.0
"""
from ModelAPI import modelAPI_ResultConstruction, featureToCompositeFeature
from model.sketcher.line import Line
from model.sketcher.circle import Circle
from model.sketcher.arc import Arc
+from model.sketcher.mirror import Mirror
from model.roots import Interface
from model.tools import Selection
-def addSketch(doc, plane):
- """Add a Sketch feature to the Part or PartSet and return an interface
- on it.
+def addSketch(document, plane):
+ """Add a sketch to a Part or PartSet.
- A Sketch object is instanciated with a feature as input parameter
- it provides an interface for manipulation of the feature data.
- :return: interface on the feature
- :rtype: Sketch"""
- feature = featureToCompositeFeature(doc.addFeature("Sketch"))
+ Arguments:
+ document(ModelAPI_Document): part or partset document
+ plane(geom.Ax3): plane on wich the sketch is built
+
+ Returns:
+ Sketch: sketch object
+ """
+ feature = featureToCompositeFeature(document.addFeature("Sketch"))
return Sketch(feature, plane)
class Sketch(Interface):
- """Interface on a Sketch feature."""
+ """Interface class for Sketch feature."""
def __init__(self, feature, *args):
"""Initialize a 2D Sketch on the given plane.
)
self._external = self._feature.data().selection("External")
- assert(self._origin)
- assert(self._dir_x)
- assert(self._norm)
- assert(self._external)
-
- # Entities used for building the result shape
- self._selection = None
-
- if not args:
- return
-
- plane = args[0]
-
- # self.resultype ="Face" # Type of Sketch result
- if isinstance(plane, str):
- self.__sketchOnFace(plane)
- else:
- self.__sketchOnPlane(plane)
+ # If no arguments are given the attributes of the feature
+ # are not Initialized
+ if args is not None:
+ plane = args[0]
+ if isinstance(plane, str):
+ self.__sketchOnFace(plane)
+ else:
+ self.__sketchOnPlane(plane)
def __sketchOnPlane(self, plane):
"""Create the sketch on a plane."""
#-------------------------------------------------------------
def addPoint(self, *args):
- """Add a point to this Sketch."""
+ """Add a point to the sketch."""
+ if not args:
+ raise TypeError("No arguments given")
point_feature = self._feature.addFeature("SketchPoint")
return Point(point_feature, *args)
def addLine(self, *args):
- """Add a line to this Sketch."""
+ """Add a line to the sketch.
+
+ .. function:: addLine(name)
+ Select an existing line. The line is added to the sketch with a rigid
+ constraint (it cannot be modified by the sketch)
+
+ Arguments:
+ name(str): name of an existing line
+
+ .. function:: addLine(start, end)
+ Create a line by points
+
+ Arguments:
+ start(point): start point of the line
+ end(point): end point of the line
+
+ .. function:: addLine(start_x, start_y, end_x, end_y)
+ Create a line by coordinates
+
+ Arguments:
+ start_x(double): start point x coordinate
+ """
+ if not args:
+ raise TypeError("No arguments given")
line_feature = self._feature.addFeature("SketchLine")
line_interface = Line(line_feature, *args)
# if the line is created by name add a rigid constraint
def addCircle(self, *args):
"""Add a circle to this Sketch."""
+ if not args:
+ raise TypeError("No arguments given")
circle_feature = self._feature.addFeature("SketchCircle")
return Circle(circle_feature, *args)
- def addArc(self, *args):
- """Add an arc to this Sketch."""
+ def addArc(self, *args, **kwargs):
+ """Add an arc of circle to the sketch and return an arc object.
+
+ Two different syntaxes are allowed:
+
+ .. function:: addArc(center, start, end)
+
+ Arguments:
+ center (point): center of the arc
+ start (point): start point of the arc
+ end (point): end point of the arc
+
+ .. function:: addArc(center_x, center_y, start_x, start_y, end_x, end_y)
+
+ Same as above but with coordinates
+
+ Returns:
+ Arc: arc object
+ Raises:
+ TypeError: if no argument is provided
+ """
+ if not args:
+ raise TypeError("No arguments given")
arc_feature = self._feature.addFeature("SketchArc")
- return Arc(arc_feature, *args)
+ return Arc(arc_feature, *args, **kwargs)
#-------------------------------------------------------------
#
def setCoincident(self, p1, p2):
"""Set coincident the two given points and add the corresponding
constraint to this Sketch."""
+ # assert(p1 and p2) NOTE : if an argument is missing python
+ # will raise TypeError by itself.
+ # It seems better to check only that provided arguments are not
+ # None
+ if p1 is None or p2 is None:
+ raise TypeError("NoneType argument given")
constraint = self._feature.addFeature("SketchConstraintCoincidence")
- constraint.data().refattr("ConstraintEntityA").setAttr(p1)
- constraint.data().refattr("ConstraintEntityB").setAttr(p2)
- self._execute()
+ self._fillAttribute(constraint.refattr("ConstraintEntityA"), p1)
+ self._fillAttribute(constraint.refattr("ConstraintEntityB"), p2)
+ self.execute()
return constraint
def setParallel(self, l1, l2):
"""Set parallel the two given lines and add the corresponding
constraint to this Sketch."""
+ if l1 is None or l2 is None:
+ raise TypeError("NoneType argument given")
constraint = self._feature.addFeature("SketchConstraintParallel")
constraint.data().refattr("ConstraintEntityA").setObject(l1)
constraint.data().refattr("ConstraintEntityB").setObject(l2)
- self._execute()
+ self.execute()
return constraint
def setPerpendicular(self, l1, l2):
"""Set perpendicular the two given lines and add the corresponding
constraint to this Sketch."""
+ if l1 is None or l2 is None:
+ raise TypeError("NoneType argument given")
constraint = self._feature.addFeature("SketchConstraintPerpendicular")
constraint.data().refattr("ConstraintEntityA").setObject(l1)
constraint.data().refattr("ConstraintEntityB").setObject(l2)
- self._execute()
+ self.execute()
return constraint
def setHorizontal(self, line):
"""Set horizontal the given line and add the corresponding
constraint to this Sketch."""
+ if line is None:
+ raise TypeError("NoneType argument given")
constraint = self._feature.addFeature("SketchConstraintHorizontal")
constraint.data().refattr("ConstraintEntityA").setObject(line)
- self._execute()
+ self.execute()
return constraint
def setVertical(self, line):
"""Set vertical the given line and add the corresponding
constraint to this Sketch."""
+ if line is None:
+ raise TypeError("NoneType argument given")
constraint = self._feature.addFeature("SketchConstraintVertical")
constraint.data().refattr("ConstraintEntityA").setObject(line)
- self._execute()
+ self.execute()
return constraint
def setDistance(self, point, line, length):
"""Set the distance between the given point and line, and add
the corresponding constraint to this Sketch."""
+ if point is None or line is None:
+ raise TypeError("NoneType argument given")
constraint = self._feature.addFeature("SketchConstraintDistance")
- if isinstance(line, str):
+ if isinstance(line, basestring):
# Add the edge identified by the given topological name
# to this Sketch
line = self.addLine(line).result()
constraint.data().refattr("ConstraintEntityA").setAttr(point)
constraint.data().refattr("ConstraintEntityB").setObject(line)
constraint.data().real("ConstraintValue").setValue(length)
- self._execute()
+ self.execute()
return constraint
def setLength(self, line, length):
"""Set the length of the given line and add the corresponding
constraint to this Sketch."""
+ if line is None:
+ raise TypeError("NoneType argument given")
constraint = self._feature.addFeature("SketchConstraintLength")
constraint.data().refattr("ConstraintEntityA").setObject(line)
- constraint.data().real("ConstraintValue").setValue(length)
- self._execute()
+ self._fillAttribute(constraint.real("ConstraintValue"), length)
+ self.execute()
return constraint
def setRadius(self, circle, radius):
"""Set the radius of the given circle and add the corresponding
constraint to this Sketch."""
constraint = self._feature.addFeature("SketchConstraintRadius")
- constraint.data().refattr("ConstraintEntityA").setObject(circle)
- constraint.data().real("ConstraintValue").setValue(radius)
- self._execute()
+ self._fillAttribute(constraint.refattr("ConstraintEntityA"), circle)
+ self._fillAttribute(constraint.real("ConstraintValue"), radius)
+ self.execute()
return constraint
def setEqual(self, object_1, object_2):
constraint = self._feature.addFeature("SketchConstraintEqual")
constraint.data().refattr("ConstraintEntityA").setObject(object_1)
constraint.data().refattr("ConstraintEntityB").setObject(object_2)
- self._execute()
+ self.execute()
return constraint
def setAngle(self, line_1, line_2, angle):
constraint.data().refattr("ConstraintEntityA").setObject(line_1)
constraint.data().refattr("ConstraintEntityB").setObject(line_2)
constraint.data().real("ConstraintValue").setValue(angle)
- self._execute()
+ self.execute()
return constraint
def setTangent(self, object_1, object_2):
"""Set a tangential continuity between two objects
at their coincidence point."""
+ if object_1 is None or object_2 is None:
+ raise TypeError("NoneType argument given")
constraint = self._feature.addFeature("SketchConstraintTangent")
constraint.data().refattr("ConstraintEntityA").setObject(object_1)
constraint.data().refattr("ConstraintEntityB").setObject(object_2)
- self._execute()
+ self.execute()
return constraint
- def setFillet(self, line_1, line_2, radius):
- """Set a fillet constraint between the 3 given lines with the given
+ def setFillet(self, *args):
+ """Set a fillet constraint between the 2 given lines with the given
filleting radius."""
+ assert(args)
constraint = self._feature.addFeature("SketchConstraintFillet")
- constraint.data().refattr("ConstraintEntityA").setObject(line_1)
- constraint.data().refattr("ConstraintEntityB").setObject(line_2)
- constraint.data().real("ConstraintValue").setValue(radius)
- self._execute()
+ if len(args) == 3:
+ line_1, line_2, radius = args
+ constraint.data().refattr("ConstraintEntityA").setObject(line_1)
+ constraint.data().reflist("ConstraintEntityB").clear()
+ constraint.data().reflist("ConstraintEntityB").append(line_2)
+ elif len(args) == 2:
+ point, radius = args
+ self._fillAttribute(constraint.data().refattrlist("ConstraintEntityA"), [point])
+ self._fillAttribute(constraint.real("ConstraintValue"), radius)
+ self.execute()
+ return constraint
+
+ def setRigid(self, object_):
+ """Set a rigid constraint on a given object."""
+ constraint = self._feature.addFeature("SketchConstraintRigid")
+ self._fillAttribute(constraint.refattr("ConstraintEntityA"), object_)
+ self.execute()
return constraint
+ #-------------------------------------------------------------
+ #
+ # Transformation constraints
+ #
+ #-------------------------------------------------------------
+
+ def addMirror(self, mirror_line, sketch_objects):
+ """Add a mirror transformation of the given objects to the sketch.
+
+ This transformation is a constraint.
+
+ :return: interface to the constraint
+ :rtype: Mirror object
+ """
+ mirror_constraint = self._feature.addFeature("SketchConstraintMirror")
+ mirror_interface = Mirror(mirror_constraint, mirror_line, sketch_objects)
+ self.execute()
+ return mirror_interface
+
+
#-------------------------------------------------------------
#
# Edition of Dimensional Constraints
# Adding and connecting next lines
for c2 in coords[2:]:
line_2 = self.addLine(c1, c2)
- self.setCoincident(line_1.endPointData(), line_2.startPointData())
+ self.setCoincident(line_1.endPoint(), line_2.startPoint())
polyline.append(line_2)
c1 = c2
line_1 = line_2
cn = coords[len(coords) - 1]
ln = self.addLine(cn, c0)
self.setCoincident(
- pg[len(coords) - 2].endPointData(), ln.startPointData()
+ pg[len(coords) - 2].endPoint(), ln.startPoint()
)
self.setCoincident(
- ln.endPointData(), pg[0].startPointData()
+ ln.endPoint(), pg[0].startPoint()
)
pg.append(ln)
return pg
geometry of this Sketch.
"""
if len(args) == 0:
- self._selection = modelAPI_ResultConstruction(
+ wire = modelAPI_ResultConstruction(
self._feature.firstResult()
).shape()
elif len(args) == 1:
- self._selection = args[0].shape()
+ wire = args[0].shape()
else:
raise Exception("not yet implemented")
# TODO: simple version now, should be a list of selected faces
- return [Selection(self.result(), self.buildShape())]
+ return [Selection(self.result(), self.buildShape(wire))]
- def buildShape(self):
+ def buildShape(self, wire):
"""Build the result Shape of this Sketch according to the
selected geometrical entities."""
o = self._origin.pnt()
# The faces are kept otherwise they are destroyed at exit
faces = ShapeList()
- GeomAlgoAPI_SketchBuilder.createFaces(o, dx, n, self._selection, faces)
+ GeomAlgoAPI_SketchBuilder.createFaces(o, dx, n, wire, faces)
# TODO: Deal with several faces
return faces[0]