Salome HOME
[PythonAPI / sketcher] Added methods for sketch features modification
[modules/shaper.git] / src / PythonAPI / model / sketcher / sketch.py
index f32185c709044c7fd2168104c14f0d00dd9cdb44..04f6030313e2a85f4356ad9f66894ae86683d987 100644 (file)
@@ -1,21 +1,25 @@
 """Sketch Feature Interface
 Author: Daniel Brunier-Coulin with contribution by Mikhail Ponikarov
 """Sketch Feature Interface
 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
 """
 
 from ModelAPI import modelAPI_ResultConstruction, featureToCompositeFeature
 from GeomDataAPI import geomDataAPI_Point, geomDataAPI_Dir
 from GeomAlgoAPI import GeomAlgoAPI_SketchBuilder, ShapeList
 Copyright (C) 2014-20xx CEA/DEN, EDF R&D
 """
 
 from ModelAPI import modelAPI_ResultConstruction, featureToCompositeFeature
 from GeomDataAPI import geomDataAPI_Point, geomDataAPI_Dir
 from GeomAlgoAPI import GeomAlgoAPI_SketchBuilder, ShapeList
+
 from model.sketcher.point import Point
 from model.sketcher.line import Line
 from model.sketcher.circle import Circle
 from model.sketcher.arc import Arc
 from model.roots import Interface
 from model.sketcher.point import Point
 from model.sketcher.line import Line
 from model.sketcher.circle import Circle
 from model.sketcher.arc import Arc
 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(doc, plane):
     """Add a Sketch feature to the Part or PartSet and return an interface
     on it.
-    
+
     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
     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
@@ -25,42 +29,56 @@ def addSketch(doc, plane):
 
 class Sketch(Interface):
     """Interface on a Sketch feature."""
 
 class Sketch(Interface):
     """Interface on a Sketch feature."""
-    def __init__(self, feature, plane):
+    def __init__(self, feature, *args):
         """Initialize a 2D Sketch on the given 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.
         """
         Interface.__init__(self, feature)
         assert(self._feature.getKind() == "Sketch")
         The plane can be defined either by:
         - a 3D axis system (geom.Ax3),
         - an existing face identified by its topological name.
         """
         Interface.__init__(self, feature)
         assert(self._feature.getKind() == "Sketch")
-        
-        # Entities used for building the result shape
-        self._selection = None
+
+        self._origin = geomDataAPI_Point(
+            self._feature.data().attribute("Origin")
+            )
+        self._dir_x = geomDataAPI_Dir(
+            self._feature.data().attribute("DirX")
+            )
+        self._norm = geomDataAPI_Dir(
+            self._feature.data().attribute("Norm")
+            )
+        self._external = self._feature.data().selection("External")
+
+        assert(self._origin)
+        assert(self._dir_x)
+        assert(self._norm)
+        assert(self._external)
+
+        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)
         #   self.resultype ="Face" # Type of Sketch result
         if isinstance(plane, str):
             self.__sketchOnFace(plane)
         else:
             self.__sketchOnPlane(plane)
+        pass
 
     def __sketchOnPlane(self, plane):
         """Create the sketch on a plane."""
         origin = plane.location()
         normal = plane.direction()
         x_direction = plane.xDirection()
 
     def __sketchOnPlane(self, plane):
         """Create the sketch on a plane."""
         origin = plane.location()
         normal = plane.direction()
         x_direction = plane.xDirection()
-        geomDataAPI_Point( 
-            self._feature.data().attribute("Origin") 
-            ).setValue(origin.x(), origin.y(), origin.z())
-        geomDataAPI_Dir( 
-            self._feature.data().attribute("DirX") 
-            ).setValue(x_direction.x(), x_direction.y(), x_direction.z())
-        geomDataAPI_Dir( 
-            self._feature.data().attribute("Norm") 
-            ).setValue(normal.x(), normal.y(), normal.z() )
+        self._origin.setValue(origin.x(), origin.y(), origin.z())
+        self._norm.setValue(normal.x(), normal.y(), normal.z())
+        self._dir_x.setValue(x_direction.x(), x_direction.y(), x_direction.z())
 
     def __sketchOnFace(self, name):
         """Initialize the sketch on a face given by its name."""
 
     def __sketchOnFace(self, name):
         """Initialize the sketch on a face given by its name."""
-        self._feature.data().selection("External").selectSubShape("FACE", name)
+        self._external.selectSubShape("FACE", name)
 
     #-------------------------------------------------------------
     #
 
     #-------------------------------------------------------------
     #
@@ -80,22 +98,22 @@ class Sketch(Interface):
         # if the line is created by name add a rigid constraint
         # to the created line
         if len(args) == 1 and isinstance(args[0], str):
         # if the line is created by name add a rigid constraint
         # to the created line
         if len(args) == 1 and isinstance(args[0], str):
-            constraint = sketch.addFeature("SketchConstraintRigid")
+            constraint = self._feature.addFeature("SketchConstraintRigid")
             constraint.refattr("ConstraintEntityA").setObject(
                 line_feature.firstResult()
                 )
         return line_interface
             constraint.refattr("ConstraintEntityA").setObject(
                 line_feature.firstResult()
                 )
         return line_interface
-    
+
     def addCircle(self, *args):
         """Add a circle to this Sketch."""
         circle_feature = self._feature.addFeature("SketchCircle")
         return Circle(circle_feature, *args)
     def addCircle(self, *args):
         """Add a circle to this Sketch."""
         circle_feature = self._feature.addFeature("SketchCircle")
         return Circle(circle_feature, *args)
-    
+
     def addArc(self, *args):
         """Add an arc to this Sketch."""
         arc_feature = self._feature.addFeature("SketchArc")
         return Arc(arc_feature, *args)
     def addArc(self, *args):
         """Add an arc to this Sketch."""
         arc_feature = self._feature.addFeature("SketchArc")
         return Arc(arc_feature, *args)
-  
+
     #-------------------------------------------------------------
     #
     # Creation of Geometrical and Dimensional Constraints
     #-------------------------------------------------------------
     #
     # Creation of Geometrical and Dimensional Constraints
@@ -103,111 +121,123 @@ class Sketch(Interface):
     #-------------------------------------------------------------
 
     def setCoincident(self, p1, p2):
     #-------------------------------------------------------------
 
     def setCoincident(self, p1, p2):
-        """Set coincident the two given points and add the corresponding 
+        """Set coincident the two given points and add the corresponding
         constraint to this Sketch."""
         constraint to this Sketch."""
+        assert(p1 and p2)
         constraint = self._feature.addFeature("SketchConstraintCoincidence")
         constraint.data().refattr("ConstraintEntityA").setAttr(p1)
         constraint.data().refattr("ConstraintEntityB").setAttr(p2)
         constraint = self._feature.addFeature("SketchConstraintCoincidence")
         constraint.data().refattr("ConstraintEntityA").setAttr(p1)
         constraint.data().refattr("ConstraintEntityB").setAttr(p2)
+        self._execute()
         return constraint
 
     def setParallel(self, l1, l2):
         return constraint
 
     def setParallel(self, l1, l2):
-        """Set parallel the two given lines and add the corresponding 
+        """Set parallel the two given lines and add the corresponding
         constraint to this Sketch."""
         constraint to this Sketch."""
+        assert(l1 and l2)
         constraint = self._feature.addFeature("SketchConstraintParallel")
         constraint.data().refattr("ConstraintEntityA").setObject(l1)
         constraint.data().refattr("ConstraintEntityB").setObject(l2)
         constraint = self._feature.addFeature("SketchConstraintParallel")
         constraint.data().refattr("ConstraintEntityA").setObject(l1)
         constraint.data().refattr("ConstraintEntityB").setObject(l2)
+        self._execute()
         return constraint
 
     def setPerpendicular(self, l1, l2):
         return constraint
 
     def setPerpendicular(self, l1, l2):
-        """Set perpendicular the two given lines and add the corresponding 
+        """Set perpendicular the two given lines and add the corresponding
         constraint to this Sketch."""
         constraint to this Sketch."""
+        assert(l1 and l2)
         constraint = self._feature.addFeature("SketchConstraintPerpendicular")
         constraint.data().refattr("ConstraintEntityA").setObject(l1)
         constraint.data().refattr("ConstraintEntityB").setObject(l2)
         constraint = self._feature.addFeature("SketchConstraintPerpendicular")
         constraint.data().refattr("ConstraintEntityA").setObject(l1)
         constraint.data().refattr("ConstraintEntityB").setObject(l2)
+        self._execute()
         return constraint
         return constraint
-    
+
     def setHorizontal(self, line):
     def setHorizontal(self, line):
-        """Set horizontal the given line and add the corresponding 
+        """Set horizontal the given line and add the corresponding
         constraint to this Sketch."""
         constraint = self._feature.addFeature("SketchConstraintHorizontal")
         constraint.data().refattr("ConstraintEntityA").setObject(line)
         constraint to this Sketch."""
         constraint = self._feature.addFeature("SketchConstraintHorizontal")
         constraint.data().refattr("ConstraintEntityA").setObject(line)
+        self._execute()
         return constraint
         return constraint
-    
+
     def setVertical(self, line):
     def setVertical(self, line):
-        """Set vertical the given line and add the corresponding 
+        """Set vertical the given line and add the corresponding
         constraint to this Sketch."""
         constraint = self._feature.addFeature("SketchConstraintVertical")
         constraint.data().refattr("ConstraintEntityA").setObject(line)
         constraint to this Sketch."""
         constraint = self._feature.addFeature("SketchConstraintVertical")
         constraint.data().refattr("ConstraintEntityA").setObject(line)
+        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."""
         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."""
+        assert(point and line)
         constraint = self._feature.addFeature("SketchConstraintDistance")
         constraint = self._feature.addFeature("SketchConstraintDistance")
-        if isinstance(line, str):
-            # Add the edge identified by the given topological name 
+        if isinstance(line, basestring):
+            # Add the edge identified by the given topological name
             # to this Sketch
             # to this Sketch
-            line = self.addLine(line).result()   
+            line = self.addLine(line).result()
+            assert(line)
         constraint.data().refattr("ConstraintEntityA").setAttr(point)
         constraint.data().refattr("ConstraintEntityB").setObject(line)
         constraint.data().real("ConstraintValue").setValue(length)
         constraint.data().refattr("ConstraintEntityA").setAttr(point)
         constraint.data().refattr("ConstraintEntityB").setObject(line)
         constraint.data().real("ConstraintValue").setValue(length)
-        self._feature.execute()
+        self._execute()
         return constraint
 
     def setLength(self, line, length):
         return constraint
 
     def setLength(self, line, length):
-        """Set the length of the given line and add the corresponding 
+        """Set the length of the given line and add the corresponding
         constraint to this Sketch."""
         constraint to this Sketch."""
+        assert(line)
         constraint = self._feature.addFeature("SketchConstraintLength")
         constraint.data().refattr("ConstraintEntityA").setObject(line)
         constraint.data().real("ConstraintValue").setValue(length)
         constraint = self._feature.addFeature("SketchConstraintLength")
         constraint.data().refattr("ConstraintEntityA").setObject(line)
         constraint.data().real("ConstraintValue").setValue(length)
-        self._feature.execute()
+        self._execute()
         return constraint
         return constraint
-    
+
     def setRadius(self, circle, radius):
     def setRadius(self, circle, radius):
-        """Set the radius of the given circle and add the corresponding 
+        """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)
         constraint to this Sketch."""
         constraint = self._feature.addFeature("SketchConstraintRadius")
         constraint.data().refattr("ConstraintEntityA").setObject(circle)
         constraint.data().real("ConstraintValue").setValue(radius)
+        self._execute()
         return constraint
         return constraint
-    
+
     def setEqual(self, object_1, object_2):
         """Set the radii of two circles or the length of two lines equal.
     def setEqual(self, object_1, object_2):
         """Set the radii of two circles or the length of two lines equal.
-        
+
         The corresponding constraint is added to the sketch"""
         constraint = self._feature.addFeature("SketchConstraintEqual")
         constraint.data().refattr("ConstraintEntityA").setObject(object_1)
         constraint.data().refattr("ConstraintEntityB").setObject(object_2)
         The corresponding constraint is added to the sketch"""
         constraint = self._feature.addFeature("SketchConstraintEqual")
         constraint.data().refattr("ConstraintEntityA").setObject(object_1)
         constraint.data().refattr("ConstraintEntityB").setObject(object_2)
-        self._feature.execute()
+        self._execute()
         return constraint
         return constraint
-    
+
     def setAngle(self, line_1, line_2, angle):
     def setAngle(self, line_1, line_2, angle):
-        """Set the angle between the given 2 lines and add the corresponding 
+        """Set the angle between the given 2 lines and add the corresponding
         constraint to the sketch."""
         constraint = self._feature.addFeature("SketchConstraintAngle")
         constraint.data().refattr("ConstraintEntityA").setObject(line_1)
         constraint.data().refattr("ConstraintEntityB").setObject(line_2)
         constraint.data().real("ConstraintValue").setValue(angle)
         constraint to the sketch."""
         constraint = self._feature.addFeature("SketchConstraintAngle")
         constraint.data().refattr("ConstraintEntityA").setObject(line_1)
         constraint.data().refattr("ConstraintEntityB").setObject(line_2)
         constraint.data().real("ConstraintValue").setValue(angle)
-        self._feature.execute()
+        self._execute()
         return constraint
         return constraint
-    
+
     def setTangent(self, object_1, object_2):
     def setTangent(self, object_1, object_2):
-        """Set a tangential continuity between two objects 
+        """Set a tangential continuity between two objects
         at their coincidence point."""
         constraint = self._feature.addFeature("SketchConstraintTangent")
         constraint.data().refattr("ConstraintEntityA").setObject(object_1)
         constraint.data().refattr("ConstraintEntityB").setObject(object_2)
         at their coincidence point."""
         constraint = self._feature.addFeature("SketchConstraintTangent")
         constraint.data().refattr("ConstraintEntityA").setObject(object_1)
         constraint.data().refattr("ConstraintEntityB").setObject(object_2)
-        self._feature.execute()
+        self._execute()
         return constraint
         return constraint
-    
+
     def setFillet(self, line_1, line_2, radius):
     def setFillet(self, line_1, line_2, radius):
-        """Set a fillet constraint between the 3 given lines with the given 
+        """Set a fillet constraint between the 3 given lines with the given
         filleting radius."""
         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)
         filleting radius."""
         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._feature.execute()
+        self._execute()
         return constraint
 
     #-------------------------------------------------------------
         return constraint
 
     #-------------------------------------------------------------
@@ -219,16 +249,16 @@ class Sketch(Interface):
     def setValue(self, constraint, value):
         """Modify the value of the given dimensional constraint."""
         constraint.data().real("ConstraintValue").setValue(value)
     def setValue(self, constraint, value):
         """Modify the value of the given dimensional constraint."""
         constraint.data().real("ConstraintValue").setValue(value)
-     
+
     #-------------------------------------------------------------
     #
     # Macro functions combining geometry creation and constraints
     #
     #-------------------------------------------------------------
     #-------------------------------------------------------------
     #
     # Macro functions combining geometry creation and constraints
     #
     #-------------------------------------------------------------
-     
+
     def addPolyline(self, *coords):
         """Add a poly-line to this Sketch.
     def addPolyline(self, *coords):
         """Add a poly-line to this Sketch.
-        
+
         The end of consecutive segments are defined as coincident.
         """
         c0 = coords[0]
         The end of consecutive segments are defined as coincident.
         """
         c0 = coords[0]
@@ -247,7 +277,7 @@ class Sketch(Interface):
 
     def addPolygon(self, *coords):
         """Add a polygon to this Sketch.
 
     def addPolygon(self, *coords):
         """Add a polygon to this Sketch.
-        
+
         The end of consecutive segments are defined as coincident.
         """
         pg = self.addPolyline(*coords)
         The end of consecutive segments are defined as coincident.
         """
         pg = self.addPolyline(*coords)
@@ -271,32 +301,34 @@ class Sketch(Interface):
     #-------------------------------------------------------------
 
     def selectFace(self, *args):
     #-------------------------------------------------------------
 
     def selectFace(self, *args):
-        """Select the geometrical entities of this Sketch on which 
+        """Select the geometrical entities of this Sketch on which
         the result Face must be built.
         the result Face must be built.
-        
-        When no entity is given, the face is based on all existing 
+
+        When no entity is given, the face is based on all existing
         geometry of this Sketch.
         """
         if len(args) == 0:
         geometry of this Sketch.
         """
         if len(args) == 0:
-            self._selection = modelAPI_ResultConstruction( 
-                self._feature.firstResult()).shape()
+            wire = modelAPI_ResultConstruction(
+                self._feature.firstResult()
+                ).shape()
         elif len(args) == 1:
         elif len(args) == 1:
-            self._selection = args[0].shape()
+            wire = args[0].shape()
         else:
             raise Exception("not yet implemented")
         else:
             raise Exception("not yet implemented")
-        return self
+        # TODO: simple version now, should be a list of selected faces
+        return [Selection(self.result(), self.buildShape(wire))]
 
 
-    def buildShape(self):
-        """Build the result Shape of this Sketch according to the 
+    def buildShape(self, wire):
+        """Build the result Shape of this Sketch according to the
         selected geometrical entities."""
         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()
+        o = self._origin.pnt()
+        dx = self._dir_x.dir()
+        n = self._norm.dir()
 
         # The faces are kept otherwise they are destroyed at exit
         faces = ShapeList()
 
         # The faces are kept otherwise they are destroyed at exit
         faces = ShapeList()
-        GeomAlgoAPI_SketchBuilder.createFaces(o, dx, n, self._selection, faces)
-        #TODO: Deal with several faces 
+        GeomAlgoAPI_SketchBuilder.createFaces(o, dx, n, wire, faces)
+        # TODO: Deal with several faces
         return faces[0]
 
     def result(self):
         return faces[0]
 
     def result(self):