]> SALOME platform Git repositories - modules/gui.git/commitdiff
Salome HOME
IMP: pluginpreview
authorboulant <boulant>
Mon, 13 Feb 2012 10:08:07 +0000 (10:08 +0000)
committerboulant <boulant>
Mon, 13 Feb 2012 10:08:07 +0000 (10:08 +0000)
doc/salome/gui/input/using_pluginsmanager.doc
src/SalomeApp/pluginsdemo/Makefile.am
src/SalomeApp/pluginsdemo/myhelper.py [deleted file]
src/SalomeApp/pluginsdemo/salome_plugins.py
src/SalomeApp/pluginsdemo/tube.py [deleted file]
src/SalomeApp/pluginsdemo/tubebuilder.py [new file with mode: 0644]
src/SalomeApp/pluginsdemo/tubedialog.py
src/SalomeApp/pluginsdemo/tubedialogWithApply.py [deleted file]
src/SalomeApp/pluginsdemo/tubedialog_ui.py [new file with mode: 0644]
src/SalomeApp/pluginsdemo/xalome.py [new file with mode: 0644]

index 4ac23796c36dc524bac5fd9d5b61cac55e843921..d6f8234ffd04bd67c52b7bbde872e109e50f9358 100644 (file)
@@ -5,6 +5,7 @@
 -# \ref S1_SALOMEPLUGINS
 -# \ref S2_SALOMEPLUGINS
 -# \ref S3_SALOMEPLUGINS
+-# \ref S4_SALOMEPLUGINS
 
 \section S1_SALOMEPLUGINS Objectives
 
@@ -29,7 +30,7 @@ In this example, the end user has to write:
 -# the python script that creates the mesh from the parameters, using
    the GEOM and SMESH python interface, as in a clasic use case.
 -# the dialog box in PyQt to input the parameters
--# file salome_plugins.py that declares the plugins
+-# the file salome_plugins.py that declares the plugins
 
 This page explains only the last point.
 
@@ -64,23 +65,24 @@ proxy to your code that you can manage in a python package
 installed in the standard SALOME python directories.
 
 In this code, the variable "context" is automatically transmitted by
-the pluginmanager when you request the plugin with at least the following
-attributes:
+the pluginmanager when you request the plugin. This context provides
+you with at at least the following attributes:
 
 \code
 activeStudy = context.study
 salomegui = context.sg
 \endcode
 
-Once terminated, this script salome_plugin.py has to be moved to a
+Once written, this script salome_plugin.py has to be moved to a
 specific place on your filesystem where SALOME is programmed to search
-for plugins. The possible directories are:
+for plugins. The possible directories are (in search order):
 
--# The directory <*_ROOT_DIR>/share/salome/plugins, when this plugin
-   is developped in the framework of a SALOME module (<*_ROOT_DIR>
-   is the root installation directory of the module).
+-# The directory <*_ROOT_DIR>/share/salome/plugins/<module_name>, when
+   this plugin is developped in the framework of a SALOME module
+   (<*_ROOT_DIR> is the root installation directory of the module, and
+   <module_name> is the name of the module in low letters).
 -# The directory ~/.config/salome/Plugins for personnal end user
-   plugins
+   plugins.
 -# Any path in the shell variable SALOME_PLUGIN_PATH (each path must be
    separated by a comma ":" for unix and ";" for windows). This
    variable should be set and exported before running the SALOME application.  
@@ -141,4 +143,27 @@ salome_pluginsmanager.AddFunction('O,Vx,Vy,Vz',
 Move this script in the directory
 ~/.config/salome/Plugins, run SALOME and enjoy your new function.
 
+\section S4_SALOMEPLUGINS Other examples
+
+The GUI module provides you with some basic demo examples, located in
+the directory src/SalomeApp/pluginsdemo of the source space, and
+installed in the directory $GUI_ROOT_DIR/share/salome/plugins/gui.
+
+\note These examples are automatically installed when you install the GUI
+but are not activated. To activate the plugins, edit the file
+$GUI_ROOT_DIR/share/salome/plugins/gui/salome_plugins.py and turn the
+variable DEMO_IS_ACTIVATED to True.
+
+The demo examples are:
+-# \b trihedron: create a trihedron and display it with fit on the size 
+-# \b tube_shapewithgui: create a geom object from parameters given by a
+   dialog box.
+-# \b tube_meshwithgui: create a mesh object from parameters given by a
+   dialog box. This illustrates that a plugin can work with more than
+   one SALOME module.
+-# \b tube_shapewithguiAndPreview: same than tube_shapewithgui but with
+   an additionnal preview function (button apply in the dialog box).
+-# \b runSalomeShellSession: run a SALOME prepared shell session in a
+   xterm.
+
 */
index d602c6a7effa57370d8a789a1aa49de82bd2c4aa..ed5f9376336e6125aa6504ce40f8ac5a595a3585 100644 (file)
@@ -32,9 +32,9 @@ include $(top_srcdir)/adm_local/unix/make_common_starter.am
 #
 pluginsdir =$(salomepluginsdir)/demo
 plugins_PYTHON = \
-       salome_plugins.py      \
-       trihedron.py           \
-       tubedialog.py          \
-       tubedialogWithApply.py \
-       tube.py                \
-       myhelper.py
+       salome_plugins.py \
+       trihedron.py      \
+       tubedialog_ui.py  \
+       tubedialog.py     \
+       tubebuilder.py    \
+       xalome.py
diff --git a/src/SalomeApp/pluginsdemo/myhelper.py b/src/SalomeApp/pluginsdemo/myhelper.py
deleted file mode 100644 (file)
index 70c94b9..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-# -*- coding: iso-8859-1 -*-
-
-import salome
-from salome.geom import geomtools
-
-def addToStudy(study,shape,name):
-    '''
-    Helper function to add an object in the study. It returns the
-    associated entry so that this study could be manipulated using
-    study object functions.  
-    '''
-    studyId = study._get_StudyId()
-    geompy = geomtools.getGeompy(studyId)
-    entry = geompy.addToStudy( shape, "Tube" )
-    return entry
-
-# Available in SALOME 6.5 only
-def displayShape_version65(shapeStudyEntry):
-    gst = geomtools.GeomStudyTools()
-    gst.displayShapeByEntry(shapeStudyEntry)
-
-def eraseShape_version65(shapeStudyEntry):
-    gst = geomtools.GeomStudyTools()
-    gst.eraseShapeByEntry(shapeStudyEntry)
-
-ModeShading = 1
-DisplayMode=ModeShading
-def displayShape(shapeStudyEntry):
-    """This displays the shape specified by its entry in the study"""
-    geomgui = salome.ImportComponentGUI("GEOM")            
-    geomgui.createAndDisplayFitAllGO(shapeStudyEntry)
-    geomgui.setDisplayMode(shapeStudyEntry, DisplayMode)
-
-def eraseShape(shapeStudyEntry):
-    """
-    This erases from the viewers the shape specified by its entry
-    in the study.
-    """
-    geomgui = salome.ImportComponentGUI("GEOM")
-    eraseFromAllWindows=True
-    geomgui.eraseGO(shapeStudyEntry,eraseFromAllWindows)
index b9de4eb76958a41b742e452af5c21017e63379a9..2a2581627e85c85bc63b225564903207691f2071 100755 (executable)
@@ -1,7 +1,7 @@
 # -*- coding: iso-8859-1 -*-
 import salome_pluginsmanager
 
-DEMO_IS_ACTIVATED=False
+DEMO_IS_ACTIVATED=True
 
 # -------------------------------------------------------------------------
 # Example 1: creation of basic objects.
@@ -71,18 +71,20 @@ if DEMO_IS_ACTIVATED:
 # The plugin function (tube_shapewithgui) delegates some action to
 # dedicated imported modules (tube.py and tubedialog.py).
 #
-import tube
-import myhelper
+import tubebuilder
+import xalome
 
 # A single dialog box is defined and recycled for every call. The
 # fields are initialized with default values given by the tube factory
 # tube.py.
 import tubedialog
 dialog = tubedialog.TubeDialog()
-dialog.setData(tube.DEFAULT_RADIUS, tube.DEFAULT_LENGTH, tube.DEFAULT_WIDTH)
+dialog.setData(tubebuilder.DEFAULT_RADIUS,
+               tubebuilder.DEFAULT_LENGTH,
+               tubebuilder.DEFAULT_WIDTH)
 
 def tube_shapewithgui(context):
-    global tube, myhelper, dialog
+    global tubebuilder, xalome, dialog
     activeStudy = context.study
 
     # Get the parameter values from a gui dialog box. If the dialog is
@@ -91,9 +93,9 @@ def tube_shapewithgui(context):
     dialog.exec_()
     if dialog.wasOk():
         radius, length, width = dialog.getData()
-        shape = tube.createGeometry(activeStudy, radius, length, width)
-        entry = myhelper.addToStudy(activeStudy, shape, "Tube" )
-        myhelper.displayShape(entry)
+        shape = tubebuilder.createGeometry(activeStudy, radius, length, width)
+        entry = xalome.addToStudy(activeStudy, shape, "Tube" )
+        xalome.displayShape(entry)
 
 if DEMO_IS_ACTIVATED:
     salome_pluginsmanager.AddFunction('Tube shape from parameters',
@@ -104,7 +106,7 @@ if DEMO_IS_ACTIVATED:
 # -------------------------------------------------------------------------
 # Example 2 bis: creation of a mesh with parameters that can be read from a GUI.
 # The plugin function (tube_meshwithgui) delegates some action to
-# dedicated imported modules (tube.py and tubedialog.py).
+# dedicated imported modules (tubebuilder.py and tubedialog.py).
 #
 def tube_meshwithgui(context):
     global tube, dialog
@@ -116,7 +118,7 @@ def tube_meshwithgui(context):
     dialog.exec_()
     if dialog.wasOk():
         radius, length, width = dialog.getData()
-        mesh = tube.createModel(activeStudy, radius, length, width)
+        mesh = tubebuilder.createModel(activeStudy, radius, length, width)
 
 if DEMO_IS_ACTIVATED:
     salome_pluginsmanager.AddFunction('Tube mesh from parameters',
@@ -130,74 +132,89 @@ if DEMO_IS_ACTIVATED:
 # view because the dialog box is a not modal so that we can have
 # interaction with the complete SALOME application. This modal
 # situation requires to connect button click signal on global
-# functions named the "callback" functions.
+# functions as a "callback" mechanism.
+#
+# TODO:
+# - coloring the preview in pink
+# - store the tmp study objects in a "preview" folder
 #
-import tubedialogWithApply
-dialogWithApply = tubedialogWithApply.TubeDialogWithApply()
-dialogWithApply.setData(tube.DEFAULT_RADIUS, tube.DEFAULT_LENGTH, tube.DEFAULT_WIDTH)
+dialogWithApply = tubedialog.TubeDialogOnTopWithApply()
+dialogWithApply.setData(tubebuilder.DEFAULT_RADIUS,
+                        tubebuilder.DEFAULT_LENGTH,
+                        tubebuilder.DEFAULT_WIDTH)
 activeStudy = None
 previewShapeEntry = None
 
+DEFAULT_FOLDER_NAME="TubeList"
+DEFAULT_SHAPE_NAME="tube"
+PREVIEW_SHAPE_NAME="preview"
+
 def acceptCallback():
-    """Action to do when click on Ok"""
-    global tube, dialogWithApply, activeStudy, previewShapeEntry, deletePreviewShape
+    """Action to be done when click on Ok"""
+    global tubebuilder, xalome
+    global dialogWithApply, activeStudy
+    global previewShapeEntry, deletePreviewShape
+    global DEFAULT_FOLDER_NAME,DEFAULT_SHAPE_NAME 
+
     dialogWithApply.accept()
 
     if previewShapeEntry is not None:
         deletePreviewShape()
 
     radius, length, width = dialogWithApply.getData()
-    shape = tube.createGeometry(activeStudy, radius, length, width)
-    entry = myhelper.addToStudy(activeStudy, shape, "Tube" )
-    myhelper.displayShape(entry)
+    shape = tubebuilder.createGeometry(activeStudy, radius, length, width)
+    entry = xalome.addToStudy(activeStudy, shape, DEFAULT_SHAPE_NAME, DEFAULT_FOLDER_NAME)
+    xalome.displayShape(entry)
     
-
 def rejectCallback():
-    """Action to do when click on Cancel"""
-    global tube, dialogWithApply, activeStudy, previewShapeEntry, deletePreviewShape
+    """Action to be done when click on Cancel"""
+    global dialogWithApply, previewShapeEntry, deletePreviewShape
+
     dialogWithApply.reject()
 
     if previewShapeEntry is not None:
         deletePreviewShape()
 
+import SALOMEDS
+PREVIEW_COLOR=SALOMEDS.Color(1,0.6,1) # pink
+
 def applyCallback():
-    """Action to do when click on Apply"""
-    global tube, dialogWithApply, activeStudy, previewShapeEntry, deletePreviewShape
+    """Action to be done when click on Apply"""
+    global tubebuilder, xalome
+    global dialogWithApply, activeStudy
+    global previewShapeEntry, deletePreviewShape
+    global PREVIEW_COLOR, DEFAULT_SHAPE_NAME, DEFAULT_FOLDER_NAME, PREVIEW_SHAPE_NAME
+
     # We first have to destroy the currently displayed preview shape.
     if previewShapeEntry is not None:
         deletePreviewShape()
 
     # Then we can create the new shape with the new parameter values
     radius, length, width = dialogWithApply.getData()
-    shape = tube.createGeometry(activeStudy, radius, length, width)
-    previewShapeEntry = myhelper.addToStudy(activeStudy, shape, "Tube" )
-    myhelper.displayShape(previewShapeEntry)
+    shape = tubebuilder.createGeometry(activeStudy, radius, length, width)
+    # We apply a specific color on the shape for the preview state
+    shape.SetColor(PREVIEW_COLOR)
+    previewShapeEntry = xalome.addToStudy(activeStudy, shape, PREVIEW_SHAPE_NAME, DEFAULT_FOLDER_NAME )
+    xalome.displayShape(previewShapeEntry)
 
 def deletePreviewShape():
-    global activeStudy, previewShapeEntry
-
-    from salome.kernel.studyedit import getStudyEditor, getStudyIdFromStudy
-    from salome.kernel.services import IDToSObject, IDToObject
-
-    # WARN: please be aware that to delete a geom object, you have
-    # three operations to perform:
-    # 1. erase the shape from the viewer
-    # 2. delete the entry in the study
-    # 3. destroy the geom object
-    myhelper.eraseShape(previewShapeEntry)
-    item = IDToSObject(previewShapeEntry)
-    geomObj = IDToObject(previewShapeEntry)    
-    ste = getStudyEditor(getStudyIdFromStudy(activeStudy))
-    ste.removeItem(item,True)
-    geomObj.Destroy()
+    """This delete the shape currently being displayed as a preview"""
+    global activeStudy, previewShapeEntry, xsalome
+    xalome.deleteShape(activeStudy,previewShapeEntry)
     previewShapeEntry = None
-    
+
+# Connection of callback functions to the dialog butoon click signals
 dialogWithApply.handleAcceptWith(acceptCallback)
 dialogWithApply.handleRejectWith(rejectCallback)
 dialogWithApply.handleApplyWith(applyCallback)
 
 def tube_shapewithguiAndPreview(context):
-    global tube, dialogWithApply, activeStudy
+    """
+    This plugin open a dialog in an asynchronous mode. Then it
+    required callback functions to be associated to the button
+    signals.
+    """
+    global dialogWithApply, activeStudy
     activeStudy = context.study
     dialogWithApply.open()
 
diff --git a/src/SalomeApp/pluginsdemo/tube.py b/src/SalomeApp/pluginsdemo/tube.py
deleted file mode 100644 (file)
index 75cad21..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-# -*- coding: iso-8859-1 -*-
-
-import salome
-
-DEFAULT_RADIUS = 100
-DEFAULT_LENGTH = 300
-DEFAULT_WIDTH  = 20
-
-from salome.geom import geomtools
-
-def createGeometry(study, radius=DEFAULT_RADIUS, length=DEFAULT_LENGTH, width=DEFAULT_WIDTH):
-    '''
-    This function creates the geometry on the specified study and with
-    given parameters.
-    '''
-    print "TUBE: creating the geometry ..."
-    studyId = study._get_StudyId()
-    geompy = geomtools.getGeompy(studyId)
-
-    radius_ext = radius
-    radius_int = radius_ext - width
-
-    CylinderExt = geompy.MakeCylinderRH(radius_ext, length)
-    CylinderInt = geompy.MakeCylinderRH(radius_int, length)
-    Tube = geompy.MakeCut(CylinderExt, CylinderInt)
-    return Tube
-    
-def createGeometryWithPartition(study, radius=DEFAULT_RADIUS, length=DEFAULT_LENGTH, width=DEFAULT_WIDTH):
-    '''
-    This function create the geometrical shape with a partition so
-    that the hexaedric algorithm could be used for meshing.
-    '''
-    shape = createGeometry(study,radius,length,width)
-
-    # We have to create a partition so that we can use an hexaedric
-    # meshing algorithm.
-    studyId = study._get_StudyId()
-    geompy = geomtools.getGeompy(studyId)
-
-    print "TUBE: creating a partition ..."
-    toolPlane = geompy.MakeFaceHW(2.1*length,2.1*radius,3)
-    partition = geompy.MakePartition([shape], [toolPlane], [], [], geompy.ShapeType["SOLID"], 0, [], 0)
-    entry = geompy.addToStudy( partition, "TubeWithPartition" )
-    return partition
-    
-def createMesh(study, shape):
-    '''This function creates the mesh of the specified shape on the specified study'''
-    print "TUBE: creating the mesh ..."
-    import smesh
-
-    smesh.SetCurrentStudy(study)
-    mesh = smesh.Mesh(shape)
-    Regular_1D = mesh.Segment()
-    Nb_Segments = Regular_1D.NumberOfSegments(10)
-    Nb_Segments.SetDistrType( 0 )
-    Quadrangle_2D = mesh.Quadrangle()
-    Hexa_3D = mesh.Hexahedron()
-
-    isDone = mesh.Compute()
-
-    if salome.sg.hasDesktop():
-        smesh.SetName(mesh.GetMesh(), 'TubeMesh')
-        smesh.SetName(Regular_1D.GetAlgorithm(), 'Regular_1D')
-        smesh.SetName(Nb_Segments, 'Nb. Segments_1')
-        smesh.SetName(Quadrangle_2D.GetAlgorithm(), 'Quadrangle_2D')
-        smesh.SetName(Hexa_3D.GetAlgorithm(), 'Hexa_3D')
-        salome.sg.updateObjBrowser(0)
-
-    return mesh
-
-
-def createModel(study, radius=DEFAULT_RADIUS, length=DEFAULT_LENGTH,width=DEFAULT_WIDTH):
-    '''
-    This function create the geomtrical shape AND the associated mesh.
-    '''
-    # We first create a shape with a partition so that the hexaedric
-    # algorithm could be used.
-    shape = createGeometryWithPartition(study,radius,length,width)
-
-    # Then the mesh can be defined and computed
-    mesh = createMesh(study,shape)
-    
-def exportModel(mesh, filename):
-    '''
-    This exports the mesh to the specified filename in the med format
-    '''
-    print "TUBE: exporting mesh to file %s ..."%filename
-    import SMESH
-    mesh.ExportMED(filename, 0, SMESH.MED_V2_2, 1 )
-
-
-#
-# ===================================================================
-# Use cases and test functions
-# ===================================================================
-#
-def TEST_createGeometry():
-    salome.salome_init()
-    theStudy=salome.myStudy
-    createGeometry(theStudy)
-
-def TEST_createMesh():
-    salome.salome_init()
-    theStudy=salome.myStudy
-    shape = createGeometryWithPartition(theStudy)
-    mesh  = createMesh(theStudy, shape)
-
-def TEST_createModel():
-    salome.salome_init()
-    theStudy=salome.myStudy
-    createModel(theStudy)
-
-def TEST_exportModel():
-    salome.salome_init()
-    theStudy=salome.myStudy
-    shape = createGeometryWithPartition(theStudy)
-    mesh  = createMesh(theStudy, shape)
-    exportModel(mesh,"tubemesh.med")
-    
-if __name__ == "__main__":
-    #TEST_createGeometry()
-    #TEST_createMesh()
-    TEST_createModel()
-    #TEST_exportModel()
diff --git a/src/SalomeApp/pluginsdemo/tubebuilder.py b/src/SalomeApp/pluginsdemo/tubebuilder.py
new file mode 100644 (file)
index 0000000..75cad21
--- /dev/null
@@ -0,0 +1,124 @@
+# -*- coding: iso-8859-1 -*-
+
+import salome
+
+DEFAULT_RADIUS = 100
+DEFAULT_LENGTH = 300
+DEFAULT_WIDTH  = 20
+
+from salome.geom import geomtools
+
+def createGeometry(study, radius=DEFAULT_RADIUS, length=DEFAULT_LENGTH, width=DEFAULT_WIDTH):
+    '''
+    This function creates the geometry on the specified study and with
+    given parameters.
+    '''
+    print "TUBE: creating the geometry ..."
+    studyId = study._get_StudyId()
+    geompy = geomtools.getGeompy(studyId)
+
+    radius_ext = radius
+    radius_int = radius_ext - width
+
+    CylinderExt = geompy.MakeCylinderRH(radius_ext, length)
+    CylinderInt = geompy.MakeCylinderRH(radius_int, length)
+    Tube = geompy.MakeCut(CylinderExt, CylinderInt)
+    return Tube
+    
+def createGeometryWithPartition(study, radius=DEFAULT_RADIUS, length=DEFAULT_LENGTH, width=DEFAULT_WIDTH):
+    '''
+    This function create the geometrical shape with a partition so
+    that the hexaedric algorithm could be used for meshing.
+    '''
+    shape = createGeometry(study,radius,length,width)
+
+    # We have to create a partition so that we can use an hexaedric
+    # meshing algorithm.
+    studyId = study._get_StudyId()
+    geompy = geomtools.getGeompy(studyId)
+
+    print "TUBE: creating a partition ..."
+    toolPlane = geompy.MakeFaceHW(2.1*length,2.1*radius,3)
+    partition = geompy.MakePartition([shape], [toolPlane], [], [], geompy.ShapeType["SOLID"], 0, [], 0)
+    entry = geompy.addToStudy( partition, "TubeWithPartition" )
+    return partition
+    
+def createMesh(study, shape):
+    '''This function creates the mesh of the specified shape on the specified study'''
+    print "TUBE: creating the mesh ..."
+    import smesh
+
+    smesh.SetCurrentStudy(study)
+    mesh = smesh.Mesh(shape)
+    Regular_1D = mesh.Segment()
+    Nb_Segments = Regular_1D.NumberOfSegments(10)
+    Nb_Segments.SetDistrType( 0 )
+    Quadrangle_2D = mesh.Quadrangle()
+    Hexa_3D = mesh.Hexahedron()
+
+    isDone = mesh.Compute()
+
+    if salome.sg.hasDesktop():
+        smesh.SetName(mesh.GetMesh(), 'TubeMesh')
+        smesh.SetName(Regular_1D.GetAlgorithm(), 'Regular_1D')
+        smesh.SetName(Nb_Segments, 'Nb. Segments_1')
+        smesh.SetName(Quadrangle_2D.GetAlgorithm(), 'Quadrangle_2D')
+        smesh.SetName(Hexa_3D.GetAlgorithm(), 'Hexa_3D')
+        salome.sg.updateObjBrowser(0)
+
+    return mesh
+
+
+def createModel(study, radius=DEFAULT_RADIUS, length=DEFAULT_LENGTH,width=DEFAULT_WIDTH):
+    '''
+    This function create the geomtrical shape AND the associated mesh.
+    '''
+    # We first create a shape with a partition so that the hexaedric
+    # algorithm could be used.
+    shape = createGeometryWithPartition(study,radius,length,width)
+
+    # Then the mesh can be defined and computed
+    mesh = createMesh(study,shape)
+    
+def exportModel(mesh, filename):
+    '''
+    This exports the mesh to the specified filename in the med format
+    '''
+    print "TUBE: exporting mesh to file %s ..."%filename
+    import SMESH
+    mesh.ExportMED(filename, 0, SMESH.MED_V2_2, 1 )
+
+
+#
+# ===================================================================
+# Use cases and test functions
+# ===================================================================
+#
+def TEST_createGeometry():
+    salome.salome_init()
+    theStudy=salome.myStudy
+    createGeometry(theStudy)
+
+def TEST_createMesh():
+    salome.salome_init()
+    theStudy=salome.myStudy
+    shape = createGeometryWithPartition(theStudy)
+    mesh  = createMesh(theStudy, shape)
+
+def TEST_createModel():
+    salome.salome_init()
+    theStudy=salome.myStudy
+    createModel(theStudy)
+
+def TEST_exportModel():
+    salome.salome_init()
+    theStudy=salome.myStudy
+    shape = createGeometryWithPartition(theStudy)
+    mesh  = createMesh(theStudy, shape)
+    exportModel(mesh,"tubemesh.med")
+    
+if __name__ == "__main__":
+    #TEST_createGeometry()
+    #TEST_createMesh()
+    TEST_createModel()
+    #TEST_exportModel()
index 42b0ee4dd23b1f2bb707510890e71bbfca4313fa..f914eb422d32648ce6d5fea98fea9a50479de350 100644 (file)
@@ -1,78 +1,33 @@
-# -*- coding: iso-8859-1 -*-
 import sys
 from PyQt4 import QtGui
 from PyQt4 import QtCore
 
+from tubedialog_ui import TubeDialog_UI
 
-class TubeDialog(QtGui.QDialog):
-    def __init__(self, parent=None):
-        QtGui.QDialog.__init__(self, parent)
-        self.setupUi()
 
+class TubeDialog(TubeDialog_UI):
     def setupUi(self):
-        self.setObjectName("Dialog")
-        self.resize(400, 300)
-        self.hboxlayout = QtGui.QHBoxLayout(self)
-        self.hboxlayout.setMargin(9)
-        self.hboxlayout.setSpacing(6)
-        self.hboxlayout.setObjectName("hboxlayout")
-        self.vboxlayout = QtGui.QVBoxLayout()
-        self.vboxlayout.setMargin(0)
-        self.vboxlayout.setSpacing(6)
-        self.vboxlayout.setObjectName("vboxlayout")
-        self.hboxlayout1 = QtGui.QHBoxLayout()
-        self.hboxlayout1.setMargin(0)
-        self.hboxlayout1.setSpacing(6)
-        self.hboxlayout1.setObjectName("hboxlayout1")
-        self.vboxlayout1 = QtGui.QVBoxLayout()
-        self.vboxlayout1.setMargin(0)
-        self.vboxlayout1.setSpacing(6)
-        self.vboxlayout1.setObjectName("vboxlayout1")
-        self.lblRadius = QtGui.QLabel(self)
-        self.lblRadius.setObjectName("lblRadius")
-        self.vboxlayout1.addWidget(self.lblRadius)
-        self.lblLength = QtGui.QLabel(self)
-        self.lblLength.setObjectName("lblLength")
-        self.vboxlayout1.addWidget(self.lblLength)
-        self.lblWidth = QtGui.QLabel(self)
-        self.lblWidth.setObjectName("lblWidth")
-        self.vboxlayout1.addWidget(self.lblWidth)
-        self.hboxlayout1.addLayout(self.vboxlayout1)
-        self.vboxlayout2 = QtGui.QVBoxLayout()
-        self.vboxlayout2.setMargin(0)
-        self.vboxlayout2.setSpacing(6)
-        self.vboxlayout2.setObjectName("vboxlayout2")
-        self.txtRadius = QtGui.QLineEdit(self)
-        self.txtRadius.setObjectName("txtRadius")
-        self.vboxlayout2.addWidget(self.txtRadius)
-        self.txtLength = QtGui.QLineEdit(self)
-        self.txtLength.setObjectName("txtLength")
-        self.vboxlayout2.addWidget(self.txtLength)
-        self.txtWidth = QtGui.QLineEdit(self)
-        self.txtWidth.setObjectName("txtWidth")
-        self.vboxlayout2.addWidget(self.txtWidth)
-        self.hboxlayout1.addLayout(self.vboxlayout2)
-        self.vboxlayout.addLayout(self.hboxlayout1)
-        spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
-        self.vboxlayout.addItem(spacerItem)
-        self.buttonBox = QtGui.QDialogButtonBox(self)
-        self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
-        self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.NoButton|QtGui.QDialogButtonBox.Ok)
-        self.buttonBox.setObjectName("buttonBox")
-        self.vboxlayout.addWidget(self.buttonBox)
-        self.hboxlayout.addLayout(self.vboxlayout)
-
-        self.setWindowTitle("Tube construction")
-        self.lblRadius.setText("Rayon")
-        self.lblLength.setText("Longueur")
-        self.lblWidth.setText("Epaisseur")
-
-        QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("accepted()"), self.accept)
-        QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("rejected()"), self.reject)
+        TubeDialog_UI.setupUi(self)
+        self.handleAcceptWith(self.accept)
+        self.handleRejectWith(self.reject)
+
+    def handleAcceptWith(self,callbackFunction):
+        """This defines the function to be connected to the signal 'accepted()' (click on Ok)"""
+        QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("accepted()"), callbackFunction)
+
+    def handleRejectWith(self,callbackFunction):
+        """This defines the function to be connected to the signal 'rejected()' (click on Cancel)"""
+        QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("rejected()"), callbackFunction)
+
+    def handleApplyWith(self,callbackFunction):
+        """This defines the function to be connected to the signal 'apply()' (click on Apply)"""
+        button = self.buttonBox.button(QtGui.QDialogButtonBox.Apply)        
+        QtCore.QObject.connect(button, QtCore.SIGNAL("clicked()"), callbackFunction);
 
     def accept(self):
         '''Callback function when dialog is accepted (click Ok)'''
         self._wasOk = True
+        # We should test here the validity of values
         QtGui.QDialog.accept(self)
 
     def reject(self):
@@ -98,11 +53,32 @@ class TubeDialog(QtGui.QDialog):
 
         return radius, length, width
 
-
-def TEST_getData():
-    # This use case illustrates the MVC pattern on this simple dialog example.
-    a = QtGui.QApplication(sys.argv)
-
+    
+class TubeDialogOnTopWithApply(TubeDialog):
+    def setupUi(self):
+        """
+        This setupUi adds a button 'Apply' to execute a processing
+        tasks (ex: preview), and set a flag that keeps the dialog on
+        top of all windows.
+        """
+        TubeDialog.setupUi(self)
+        # Add a button "Apply"
+        self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|
+                                          QtGui.QDialogButtonBox.Apply|
+                                          QtGui.QDialogButtonBox.Ok)
+
+        # Keep the dialog on top of the windows
+        self.setWindowFlags(self.windowFlags() |
+                            QtCore.Qt.WindowStaysOnTopHint)
+
+
+#
+# ======================================================================
+# Unit test
+# ======================================================================
+#
+def TEST_getData_synchrone():
+    """This use case illustrates the MVC pattern on this simple dialog example""" 
     tubedialog = TubeDialog()
     tubedialog.setData(10,50,3)
     tubedialog.exec_()
@@ -110,16 +86,12 @@ def TEST_getData():
         radius, length, width = tubedialog.getData()
         print radius, length, width
 
-    sys.exit(0)
 
 def main( args ):
     a = QtGui.QApplication(sys.argv)
-
-    tubedialog = TubeDialog()
-    tubedialog.setData(10,50,3)
-    sys.exit(tubedialog.exec_())
+    TEST_getData_synchrone()
+    sys.exit(0)
 
 if __name__=="__main__":
-    #main(sys.argv)
-    TEST_getData()
+    main(sys.argv)
 
diff --git a/src/SalomeApp/pluginsdemo/tubedialogWithApply.py b/src/SalomeApp/pluginsdemo/tubedialogWithApply.py
deleted file mode 100644 (file)
index d745496..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-import sys
-from PyQt4 import QtGui
-from PyQt4 import QtCore
-
-
-from tubedialog import TubeDialog
-class TubeDialogWithApply(TubeDialog):
-    def setupUi(self):
-        """
-        This setupUi adds a button Apply to execute tasks as preview 
-        """
-        TubeDialog.setupUi(self)
-        self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|
-                                          QtGui.QDialogButtonBox.Apply|
-                                          QtGui.QDialogButtonBox.Ok)
-
-        self.setWindowFlags(self.windowFlags() |
-                            QtCore.Qt.WindowStaysOnTopHint)
-
-
-    def handleAcceptWith(self,callbackFunction):
-        QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("accepted()"), callbackFunction)
-
-    def handleRejectWith(self,callbackFunction):
-        QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("rejected()"), callbackFunction)
-
-    def handleApplyWith(self,callbackFunction):
-        button = self.buttonBox.button(QtGui.QDialogButtonBox.Apply)        
-        QtCore.QObject.connect(button, QtCore.SIGNAL("clicked()"), callbackFunction);
-
diff --git a/src/SalomeApp/pluginsdemo/tubedialog_ui.py b/src/SalomeApp/pluginsdemo/tubedialog_ui.py
new file mode 100644 (file)
index 0000000..277fd0a
--- /dev/null
@@ -0,0 +1,87 @@
+# -*- coding: iso-8859-1 -*-
+import sys
+from PyQt4 import QtGui
+from PyQt4 import QtCore
+
+
+class TubeDialog_UI(QtGui.QDialog):
+    """
+    This class defines the design of a Qt dialog box dedicated to the
+    salome plugin examples. It presents a UI form that contains
+    parameters for the spatial dimensions of geometrical object.  
+    """
+    def __init__(self, parent=None):
+        QtGui.QDialog.__init__(self, parent)
+        self.setupUi()
+
+    def setupUi(self):
+        self.setObjectName("Dialog")
+        self.resize(400, 300)
+        self.hboxlayout = QtGui.QHBoxLayout(self)
+        self.hboxlayout.setMargin(9)
+        self.hboxlayout.setSpacing(6)
+        self.hboxlayout.setObjectName("hboxlayout")
+        self.vboxlayout = QtGui.QVBoxLayout()
+        self.vboxlayout.setMargin(0)
+        self.vboxlayout.setSpacing(6)
+        self.vboxlayout.setObjectName("vboxlayout")
+        self.hboxlayout1 = QtGui.QHBoxLayout()
+        self.hboxlayout1.setMargin(0)
+        self.hboxlayout1.setSpacing(6)
+        self.hboxlayout1.setObjectName("hboxlayout1")
+        self.vboxlayout1 = QtGui.QVBoxLayout()
+        self.vboxlayout1.setMargin(0)
+        self.vboxlayout1.setSpacing(6)
+        self.vboxlayout1.setObjectName("vboxlayout1")
+        self.lblRadius = QtGui.QLabel(self)
+        self.lblRadius.setObjectName("lblRadius")
+        self.vboxlayout1.addWidget(self.lblRadius)
+        self.lblLength = QtGui.QLabel(self)
+        self.lblLength.setObjectName("lblLength")
+        self.vboxlayout1.addWidget(self.lblLength)
+        self.lblWidth = QtGui.QLabel(self)
+        self.lblWidth.setObjectName("lblWidth")
+        self.vboxlayout1.addWidget(self.lblWidth)
+        self.hboxlayout1.addLayout(self.vboxlayout1)
+        self.vboxlayout2 = QtGui.QVBoxLayout()
+        self.vboxlayout2.setMargin(0)
+        self.vboxlayout2.setSpacing(6)
+        self.vboxlayout2.setObjectName("vboxlayout2")
+        self.txtRadius = QtGui.QLineEdit(self)
+        self.txtRadius.setObjectName("txtRadius")
+        self.vboxlayout2.addWidget(self.txtRadius)
+        self.txtLength = QtGui.QLineEdit(self)
+        self.txtLength.setObjectName("txtLength")
+        self.vboxlayout2.addWidget(self.txtLength)
+        self.txtWidth = QtGui.QLineEdit(self)
+        self.txtWidth.setObjectName("txtWidth")
+        self.vboxlayout2.addWidget(self.txtWidth)
+        self.hboxlayout1.addLayout(self.vboxlayout2)
+        self.vboxlayout.addLayout(self.hboxlayout1)
+        spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
+        self.vboxlayout.addItem(spacerItem)
+        self.buttonBox = QtGui.QDialogButtonBox(self)
+        self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
+        self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.NoButton|QtGui.QDialogButtonBox.Ok)
+        self.buttonBox.setObjectName("buttonBox")
+        self.vboxlayout.addWidget(self.buttonBox)
+        self.hboxlayout.addLayout(self.vboxlayout)
+
+        self.setWindowTitle("Tube construction")
+        self.lblRadius.setText("Rayon")
+        self.lblLength.setText("Longueur")
+        self.lblWidth.setText("Epaisseur")
+
+#
+# ======================================================================
+# Unit test
+# ======================================================================
+#
+def main( args ):
+    a = QtGui.QApplication(sys.argv)
+    tubedialog = TubeDialog_UI()
+    sys.exit(tubedialog.exec_())
+
+if __name__=="__main__":
+    main(sys.argv)
+
diff --git a/src/SalomeApp/pluginsdemo/xalome.py b/src/SalomeApp/pluginsdemo/xalome.py
new file mode 100644 (file)
index 0000000..e628c04
--- /dev/null
@@ -0,0 +1,208 @@
+# -*- coding: iso-8859-1 -*-
+#
+# XALOME means "eXtension for sALOME. This module contains specific
+# helper functions that extends salome for the needs of the salome
+# plugin examples, or hide some complex technical parts of SALOME to
+# ease the global understanding of the examples.
+#
+# (gboulant - 09/02/2012)
+#
+import salome
+from salome.kernel.studyedit import getStudyEditor
+from salome.kernel.services import IDToSObject, IDToObject
+from salome.geom import geomtools
+
+# ======================================================================
+# Helper functions to add/remove a geometrical shape in/from the study
+# ======================================================================
+
+def addToStudy(study,shape,shapeName,folderName=None):
+    """
+    Add a GEOM shape in the study. It returns the associated entry
+    that corresponds to the identifier of the entry in the study. This
+    entry can be used to retrieve an object in the study. A folderName
+    can be specified. In this case, a folder with this name is first
+    created in the Geometry part of the study, and the shape study
+    object is stored in this folder of the study. 
+    """
+    studyId = study._get_StudyId()
+    geompy = geomtools.getGeompy(studyId)
+
+    if folderName is None:
+        # Insert the shape in the study by the standard way
+        entry = geompy.addToStudy( shape, shapeName )
+    else:
+        # A folder name has been specified to embed this shape. Find
+        # or create a folder with this name in the Geometry study, and
+        # then store the shape in this folder.
+        studyEditor = getStudyEditor(studyId)
+        geomStudyFolder = studyEditor.findOrCreateComponent("GEOM")
+        shapeStudyFolder = studyEditor.findOrCreateItem(geomStudyFolder,folderName)
+
+        shapeIor = salome.orb.object_to_string(shape)
+        geomgui = salome.ImportComponentGUI("GEOM")
+        shapeIcon = geomgui.getShapeTypeIcon(shapeIor)
+
+        shapeStudyObject = studyEditor.createItem(shapeStudyFolder,
+                                                  name=shapeName,
+                                                  IOR=shapeIor,
+                                                  icon=shapeIcon)
+        entry = shapeStudyObject.GetID()
+
+    return entry
+
+def removeFromStudy(study,shapeStudyEntry):
+    """
+    This removes the specified entry from the study. Note that this
+    operation does not destroy the underlying GEOM object, neither
+    erase the drawing in the viewer.
+    The underlying GEOM object is returned (so that it can be destroyed)
+    """
+    studyId = study._get_StudyId()
+    shape = IDToObject(shapeStudyEntry)    
+    studyObject = IDToSObject(shapeStudyEntry)
+    studyEditor = getStudyEditor(studyId)
+    studyEditor.removeItem(studyObject,True)
+    return shape
+
+
+# ======================================================================
+# Helper functions to display/erase a shape in/from the viewer. The
+# shape must be previously put in the study and the study entry must
+# be known.
+# ======================================================================
+
+ModeShading = 1
+DisplayMode=ModeShading
+PreviewColor=[236,163,255]
+def displayShape(shapeStudyEntry, color=None):
+    """This displays the shape specified by its entry in the study"""
+    geomgui = salome.ImportComponentGUI("GEOM")            
+    geomgui.createAndDisplayFitAllGO(shapeStudyEntry)
+    geomgui.setDisplayMode(shapeStudyEntry, DisplayMode)
+    if color is not None:
+        geomgui.setColor(shapeStudyEntry, color[0], color[1], color[2])
+
+def eraseShape(shapeStudyEntry):
+    """
+    This erases from the viewers the shape specified by its study
+    entry.
+    """
+    geomgui = salome.ImportComponentGUI("GEOM")
+    eraseFromAllWindows=True
+    geomgui.eraseGO(shapeStudyEntry,eraseFromAllWindows)
+
+# Available in SALOME 6.5 only
+def displayShape_version65(shapeStudyEntry):
+    gst = geomtools.GeomStudyTools()
+    gst.displayShapeByEntry(shapeStudyEntry)
+
+def eraseShape_version65(shapeStudyEntry):
+    gst = geomtools.GeomStudyTools()
+    gst.eraseShapeByEntry(shapeStudyEntry)
+
+
+# ======================================================================
+# Helper functions for a complete suppression of a shape from the
+# SALOME session.
+# ======================================================================
+def deleteShape(study,shapeStudyEntry):
+    """
+    This completly deletes a geom shape.
+
+    WARNING: please be aware that to delete a geom object, you have
+    three operations to perform:
+
+    1. erase the shape from the viewers
+    2. remove the entry from the study
+    3. destroy the underlying geom object
+    """
+    eraseShape(shapeStudyEntry)
+    shape = removeFromStudy(study, shapeStudyEntry)
+    shape.Destroy()
+    
+
+#
+# ======================================================================
+# Unit tests
+# ======================================================================
+#
+# To experiment this unit test, just execute this script in
+# SALOME. The script is self-consistent.
+
+def TEST_createAndDeleteShape():
+    """
+    This test is a simple use case that illustrates how to create a
+    GEOM shape in a SALOME session (create the GEOM object, put in in
+    the study, and display the shape in a viewer) and delete a shape
+    from a SALOME session (erase the shape from the viewer, delete the
+    entry from the study, and finally destroy the underlying GEOM
+    object).
+    """
+    import salome
+    salome.salome_init()
+    study   = salome.myStudy
+    studyId = salome.myStudyId
+
+    from salome.geom import geomtools
+    geompy = geomtools.getGeompy(studyId)
+
+    # --------------------------------------------------
+    # Create a first shape (GEOM object)
+    radius = 5
+    length = 100
+    cylinder = geompy.MakeCylinderRH(radius, length)
+
+    # Register the shape in the study, at the root of the GEOM
+    # folder. A name must be specified. The register operation
+    # (addToStudy) returns an identifier of the entry in the study.
+    cylinderName = "cyl.r%s.l%s"%(radius,length)
+    cylinderStudyEntry = addToStudy(study, cylinder, cylinderName)
+
+    # Display the registered shape in a viewer
+    displayShape(cylinderStudyEntry)
+
+    # --------------------------------------------------
+    # A second shape
+    radius = 10
+    sphere = geompy.MakeSphereR(radius)
+    sphereName = "sph.r%s"%radius
+    sphereStudyEntry = addToStudy(study, sphere, sphereName)
+    displayShape(sphereStudyEntry)
+
+    # --------------------------------------------------
+    # This new shape is stored in the study, but in a specific
+    # sub-folder, and is displayed in the viewer with a specific
+    # color.
+    length = 20
+    box = geompy.MakeBoxDXDYDZ(length,length,length)
+    boxName = "box.l%s"%length
+    folderName = "boxset" 
+    boxStudyEntry = addToStudy(study, box, boxName, folderName)
+    displayShape(boxStudyEntry,PreviewColor)
+
+    # --------------------------------------------------
+    # In this example, we illustrate how to erase a shape (the sphere)
+    # from the viewer. After this operation, the sphere is no longer
+    # displayed but still exists in the study. You can then redisplay
+    # it using the context menu of the SALOME object browser.
+    eraseShape(sphereStudyEntry)
+
+    # --------------------------------------------------
+    # In this last example, we completly delete an object from the
+    # SALOME session (erase from viewer, remove from study and finnaly
+    # destroy the object). This is done by a simple call to
+    # deleteShape().
+    deleteShape(study,cylinderStudyEntry)
+
+    # --------------------------------------------------
+    # At the end of the executioon of this test, you should have in
+    # the SALOME session:
+    # - the box, in a dedicated folder of the study, and displayed in the viewer
+    # - the sphere, in the standard place of the study, and not displayed 
+
+    # If you comment the deleteShape line, you should see the cylinder
+    # in the study and displayed in the viewer. 
+
+if __name__=="__main__":
+    TEST_createAndDeleteShape()