From 50eff860db4e85ac8d183d2e326eab1ccab96710 Mon Sep 17 00:00:00 2001 From: Renaud NEDELEC Date: Thu, 15 Oct 2015 11:46:02 +0200 Subject: [PATCH] [PythonAPI] Sketch interface refactoring and modifications to fit some PEP8 guidelines. --- src/PythonAPI/modeler/__init__.py | 2 +- src/PythonAPI/modeler/sketcher/sketch.py | 327 ++++++++++++----------- 2 files changed, 176 insertions(+), 153 deletions(-) diff --git a/src/PythonAPI/modeler/__init__.py b/src/PythonAPI/modeler/__init__.py index f16e4030b..76ca85c59 100644 --- a/src/PythonAPI/modeler/__init__.py +++ b/src/PythonAPI/modeler/__init__.py @@ -9,7 +9,7 @@ from roots import * # Built-in features from part import Part as addPart -from sketcher.sketch import Sketch as addSketch +from sketcher.sketch import addSketch from extrusion import Extrusion as addExtrusion from boolean import Addition as addAddition from boolean import Subtraction as addSubtraction diff --git a/src/PythonAPI/modeler/sketcher/sketch.py b/src/PythonAPI/modeler/sketcher/sketch.py index 14e53efcc..b497ff119 100644 --- a/src/PythonAPI/modeler/sketcher/sketch.py +++ b/src/PythonAPI/modeler/sketcher/sketch.py @@ -10,165 +10,188 @@ from modeler.sketcher.point import Point from modeler.sketcher.line import Line from modeler.sketcher.circle import Circle +def addSketch(doc, plane): + """Add a Sketch feature to the Part or PartSet. + + A Sketch object is instanciated with the built feature + it provides an interface for manipulating the feature data. + :return: interface on the feature + :rtype: Sketch object""" + feature = featureToCompositeFeature( doc.addFeature("Sketch") ) + return Sketch(feature, plane) class Sketch(): - - def __init__(self, doc, plane): - """Initializes a 2D Sketch on the given plane and adds the Sketch to the given Part or Partset. - The plane can be defined either by: - - a 3D axis system (geom.Ax3), - - an existing face identified by its topological name. - """ - self.my = featureToCompositeFeature( doc.addFeature("Sketch") ) - self.selection = None # Entities used for building the result shape -# self.resultype ="Face" # Type of Sketch result - if isinstance(plane, str): - self.__sketchOnFace(doc, plane) - else: - self.__sketchOnPlane(doc, plane) - - def __sketchOnPlane (self, doc, plane): - o = plane.location() - d = plane.direction() - dx = plane.xDirection() - geomDataAPI_Point( self.my.data().attribute("Origin") ).setValue( o.x(), o.y(), o.z() ) - geomDataAPI_Dir( self.my.data().attribute("DirX") ).setValue( dx.x(), dx.y(), dx.z() ) - geomDataAPI_Dir( self.my.data().attribute("Norm") ).setValue( d.x(), d.y(), d.z() ) - - def __sketchOnFace (self, doc, plane): - self.my.data().selection("External").selectSubShape("FACE", plane) + """Interface on a Sketch feature.""" + def __init__(self, feature, plane): + """Initialize a 2D Sketch on the given plane + The plane can be defined either by: + - a 3D axis system (geom.Ax3), + - an existing face identified by its topological name. + """ + self._feature = feature + self._selection = None # Entities used for building the result shape + # self.resultype ="Face" # Type of Sketch result + if isinstance(plane, str): + self.__sketchOnFace(plane) + else: + self.__sketchOnPlane(plane) + + def __sketchOnPlane (self, plane): + o = plane.location() + d = plane.direction() + dx = plane.xDirection() + geomDataAPI_Point( + self._feature.data().attribute("Origin") + ).setValue( o.x(), o.y(), o.z() ) + geomDataAPI_Dir( + self._feature.data().attribute("DirX") + ).setValue( dx.x(), dx.y(), dx.z() ) + geomDataAPI_Dir( + self._feature.data().attribute("Norm") + ).setValue( d.x(), d.y(), d.z() ) + + def __sketchOnFace (self, plane): + self._feature.data().selection("External").selectSubShape("FACE", plane) # Creation of Geometries - def addPoint (self, *args): - """Adds a point to this Sketch.""" - return Point(self.my, *args) - - def addLine (self, *args): - """Adds a line to this Sketch.""" - return Line(self.my, *args) - - def addPolyline (self, *coords): - """Adds a poly-line to this Sketch. - The end of consecutive segments are defined as coincident. - """ - c0 = coords[0] - c1 = coords[1] - pl = [] - l1 = self.addLine(c0, c1) - pl.append(l1) - # Adding and connecting next lines - for c2 in coords[2:]: - l2 = self.addLine(c1, c2) - self.setCoincident( l1.endPointData(), l2.startPointData() ) - pl.append(l2) - c1 = c2 - l1 = l2 - return pl - - def addPolygon (self, *coords): - """Adds a polygon to this Sketch. - The end of consecutive segments are defined as coincident. - """ - pg = self.addPolyline(*coords) - # Closing the poly-line supposed being defined by at least 3 points - c0 = coords[0] - cn = coords[len(coords)-1] - ln = self.addLine(cn, c0) - self.setCoincident( pg[len(coords)-2].endPointData(), ln.startPointData() ) - self.setCoincident( ln.endPointData(), pg[0].startPointData() ) - pg.append(ln) - return pg - - def addCircle (self, *args): - """Adds a circle to this Sketch.""" - return Circle(self.my, *args) - - -# Creation of Geometrical and Dimensional Constraints - - def setCoincident (self, p1, p2): - """Sets coincident the two given points and adds the corresponding constraint to this Sketch.""" - constraint = self.my.addFeature("SketchConstraintCoincidence") - constraint.data().refattr("ConstraintEntityA").setAttr(p1) - constraint.data().refattr("ConstraintEntityB").setAttr(p2) - return constraint - - def setParallel (self, l1, l2): - """Sets parallel the two given lines and adds the corresponding constraint to this Sketch.""" - constraint = self.my.addFeature("SketchConstraintParallel") - constraint.data().refattr("ConstraintEntityA").setObject(l1) - constraint.data().refattr("ConstraintEntityB").setObject(l2) - return constraint - - def setPerpendicular (self, l1, l2): - """Sets perpendicular the two given lines and adds the corresponding constraint to this Sketch.""" - constraint = self.my.addFeature("SketchConstraintPerpendicular") - constraint.data().refattr("ConstraintEntityA").setObject(l1) - constraint.data().refattr("ConstraintEntityB").setObject(l2) - return constraint - - def setDistance (self, point, line, length): - """Sets the distance between the given point and line, and adds the corresponding constraint to this Sketch.""" - constraint = self.my.addFeature("SketchConstraintDistance") - if isinstance(line, str): - line = self.addLine(line).result() # Adds the edge identified by the given topological name to this Sketch - constraint.data().refattr("ConstraintEntityA").setAttr(point) - constraint.data().refattr("ConstraintEntityB").setObject(line) - constraint.data().real("ConstraintValue").setValue(length) - self.my.execute() - return constraint - - def setLength (self, line, length): - """Sets the length of the given line and adds the corresponding constraint to this Sketch.""" - constraint = self.my.addFeature("SketchConstraintLength") - constraint.data().refattr("ConstraintEntityA").setObject(line) - constraint.data().real("ConstraintValue").setValue(length) - self.my.execute() - return constraint - - def setRadius (self, circle, radius): - """Sets the radius of the given circle and adds the corresponding constraint to this Sketch.""" - constraint = self.my.addFeature("SketchConstraintRadius") - constraint.data().refattr("ConstraintEntityA").setObject(circle) - constraint.data().real("ConstraintValue").setValue(radius) - return constraint - - -# Edition of Dimensional Constraints - - def setValue (self, constraint, value): - """Modifies the value of the given dimensional constraint.""" - constraint.data().real("ConstraintValue").setValue(value) + def addPoint (self, *args): + """Adds a point to this Sketch.""" + return Point(self._feature, *args) + + def addLine (self, *args): + """Adds a line to this Sketch.""" + return Line(self._feature, *args) + + def addPolyline (self, *coords): + """Adds a poly-line to this Sketch. + The end of consecutive segments are defined as coincident. + """ + c0 = coords[0] + c1 = coords[1] + polyline = [] + line_1 = self.addLine(c0, c1) + polyline.append(line_1) + # Adding and connecting next lines + for c2 in coords[2:]: + line_2 = self.addLine(c1, c2) + self.setCoincident( line_1.endPointData(), line_2.startPointData() ) + polyline.append(line_2) + c1 = c2 + line_1 = line_2 + return polyline + + def addPolygon (self, *coords): + """Add a polygon to this Sketch. + The end of consecutive segments are defined as coincident. + """ + pg = self.addPolyline(*coords) + # Closing the poly-line supposed being defined by at least 3 points + c0 = coords[0] + cn = coords[len(coords)-1] + ln = self.addLine(cn, c0) + self.setCoincident( pg[len(coords)-2].endPointData(), ln.startPointData() ) + self.setCoincident( ln.endPointData(), pg[0].startPointData() ) + pg.append(ln) + return pg + + def addCircle (self, *args): + """Adds a circle to this Sketch.""" + return Circle(self._feature, *args) + + + # Creation of Geometrical and Dimensional Constraints + + def setCoincident (self, p1, p2): + """Set coincident the two given points and add the corresponding + constraint to this Sketch.""" + constraint = self._feature.addFeature("SketchConstraintCoincidence") + constraint.data().refattr("ConstraintEntityA").setAttr(p1) + constraint.data().refattr("ConstraintEntityB").setAttr(p2) + return constraint + + def setParallel (self, l1, l2): + """Set parallel the two given lines and add the corresponding + constraint to this Sketch.""" + constraint = self._feature.addFeature("SketchConstraintParallel") + constraint.data().refattr("ConstraintEntityA").setObject(l1) + constraint.data().refattr("ConstraintEntityB").setObject(l2) + return constraint + + def setPerpendicular (self, l1, l2): + """Set perpendicular the two given lines and add the corresponding + constraint to this Sketch.""" + constraint = self._feature.addFeature("SketchConstraintPerpendicular") + constraint.data().refattr("ConstraintEntityA").setObject(l1) + constraint.data().refattr("ConstraintEntityB").setObject(l2) + 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.""" + constraint = self._feature.addFeature("SketchConstraintDistance") + if isinstance(line, str): + # 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._feature.execute() + return constraint + + def setLength (self, line, length): + """Set the length of the given line and add the corresponding + constraint to this Sketch.""" + constraint = self._feature.addFeature("SketchConstraintLength") + constraint.data().refattr("ConstraintEntityA").setObject(line) + constraint.data().real("ConstraintValue").setValue(length) + self._feature.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) + return constraint + + + # Edition of Dimensional Constraints + + def setValue (self, constraint, value): + """Modify the value of the given dimensional constraint.""" + constraint.data().real("ConstraintValue").setValue(value) # Getters - def selectFace (self, *args): - """Selects the geometrical entities of this Sketch on which the result Face must be built. - When no entity is given, the face is based on all existing geometry of this Sketch. - """ - #self.resultype ="Face" - if len(args) == 0: - self.selection = modelAPI_ResultConstruction( self.my.firstResult() ).shape() - elif len(args) == 1: - self.selection = args[0].shape() - else: - raise Exception("not yet implemented") - return self - - def buildShape (self): - """Builds the result Shape of this Sketch according to the selected geometrical entities.""" - o = geomDataAPI_Point( self.my.data().attribute("Origin") ).pnt() - dx = geomDataAPI_Dir( self.my.data().attribute("DirX") ).dir() - n = geomDataAPI_Dir( self.my.data().attribute("Norm") ).dir() - - faces = ShapeList() # The faces are kept otherwise they are destroyed at exit - GeomAlgoAPI_SketchBuilder.createFaces(o, dx, n, self.selection, faces) -#TODO: Deal with several faces - return faces[0] - - def result (self): - """Returns the result data of this Feature.""" - return self.my.firstResult() + def selectFace (self, *args): + """Selects the geometrical entities of this Sketch on which the result Face must be built. + When no entity is given, the face is based on all existing geometry of this Sketch. + """ + #self.resultype ="Face" + if len(args) == 0: + self._selection = modelAPI_ResultConstruction( self._feature.firstResult() ).shape() + elif len(args) == 1: + self._selection = args[0].shape() + else: + raise Exception("not yet implemented") + return self + + def buildShape (self): + """Builds the result Shape of this Sketch according to the selected geometrical entities.""" + o = geomDataAPI_Point( self._feature.data().attribute("Origin") ).pnt() + dx = geomDataAPI_Dir( self._feature.data().attribute("DirX") ).dir() + n = geomDataAPI_Dir( self._feature.data().attribute("Norm") ).dir() + + faces = ShapeList() # The faces are kept otherwise they are destroyed at exit + GeomAlgoAPI_SketchBuilder.createFaces(o, dx, n, self._selection, faces) + #TODO: Deal with several faces + return faces[0] + + def result (self): + """Returns the result data of this Feature.""" + return self._feature.firstResult() -- 2.39.2