From: cvw Date: Mon, 17 Jun 2013 14:56:45 +0000 (+0000) Subject: merge from BR_pluginMGCleaner tag mergeto_v7_main_17jun13 X-Git-Tag: V7_3_0a1~340 X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=commitdiff_plain;h=dc02ba1daa1b72f50c68e772547f8fc444843680;ds=sidebyside merge from BR_pluginMGCleaner tag mergeto_v7_main_17jun13 --- diff --git a/src/Tools/YamsPlug/YamsPlugDialog.ui b/src/Tools/YamsPlug/YamsPlugDialog.ui index 72ae1e07b..1afc115ac 100644 --- a/src/Tools/YamsPlug/YamsPlugDialog.ui +++ b/src/Tools/YamsPlug/YamsPlugDialog.ui @@ -6,8 +6,8 @@ 0 0 - 927 - 700 + 800 + 500 @@ -19,6 +19,22 @@ + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 10 + 20 + + + + @@ -38,35 +54,44 @@ Qt::Horizontal - - QSizePolicy::Minimum - - 60 + 30 20 - + - Save Params + Save + + + 18 + 18 + + - + - Load Params + Load + + + 18 + 18 + + - Default Params + Default @@ -77,8 +102,8 @@ - 338 - 25 + 30 + 20 @@ -95,6 +120,22 @@ + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 10 + 20 + + + + @@ -114,491 +155,380 @@ - 20 - 190 - 871 - 311 + 10 + 140 + 750 + 270 Optimisation - - - - 20 - 30 - 611 - 261 - - - - - - 17 - 25 - 585 - 23 - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> -<table style="-qt-table-type: root; margin-top:4px; margin-bottom:4px; margin-left:4px; margin-right:4px;"> -<tr> -<td style="border: none;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Quality improvement</span> is done by point smoothing and edge swapping</p></td></tr></table></body></html> - - - Quality improvement Only (0) - - - true - - - - - - 17 - 54 - 585 - 23 - - - - the given surface triangulation is enriched (no coarsening at all) in such away that the distance + + + + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 30 + 20 + + + + + + + + + + + Quality improvement is done by point smoothing and edge swapping. + + + Quality improvement Only (0) + + + true + + + + + + + The given surface triangulation is enriched (no coarsening at all) in such away that the distance between the elements in the final mesh and those of the initial one is bounded by auser specified tolerance value. One should use this option, to enrich the mesh where purely geometrical features may be insuficiently fine, i.e. the resulting mesh will be least as fine as the input. Mesh and the geometric features will be refined if needed as specified by the other program parameters. The meshes obtained with those settings may not be suitable for computation. - - - Pure Geometry Enrichment (G) - - - false - - - - - - 17 - 83 - 585 - 23 - - - - a uniform subdivision of the given surface triangulation is performed : + + + Pure Geometry Enrichment (G) + + + false + + + + + + + An uniform subdivision of the given surface triangulation is performed : each triangle of the given surface triangulation is considered at and is divided into identical triangles. - - - Uniform Subdivision(U) - - - false - - - - - - 17 - 112 - 585 - 23 - - - - a surface sandpapering without shrinkage of the given surface + + + Uniform Subdivision (U) + + + false + + + + + + + A surface sandpapering without shrinkage of the given surface triangulation is performed, i.e., the high curvature variations of the given surface will be smoothed out without shrinking the volume in doing so. If ridges are defined, they will be kept as they are in the resulting mesh. -This option modifies the goemetry. - - - Sand Papering (S) - - - false - - - - - - 17 - 141 - 585 - 23 - - - - The given surface triangulation is modified in such a way that the distance between +This option modifies the geometry. + + + Sandpapering (S) + + + false + + + + + + + The given surface triangulation is modified in such a way that the distance between the elements in the final mesh and those of the initial one is bounded by a user specfied tolerance value. One should use this option, to coarsen when a purely geometrical mesh is needed. (a mesh that keeps and obeys its geometric features only.) The meshes obtained with this option are usually not suitable for computation because anisotropic elements may be generated - - - Geometrical Mesh : Coarsening(-2) - - - - - - 17 - 170 - 585 - 23 - - - - The given surface triangulation is modified in such a way that the distance between + + + Geometrical Mesh : Coarsening (-2) + + + + + + + The given surface triangulation is modified in such a way that the distance between the elements in the final mesh and those of the initial one is bounded by a user specfied tolerance value. One should use this option, to coarsen and enrich when a purely geometrical mesh is needed. (a mesh that keeps and obeys its geometric features only.) The meshes obtained with this setting are usually not suitable for computation because anisotropic elements may be generated - - - Geometrical Mesh : Coarsening and Enrichment (2) - - - - - - 17 - 199 - 585 - 23 - - - - The given surface triangulation is modfied in accordance to a size map. + + + Geometrical Mesh : Coarsening and Enrichment (2) + + + + + + + The given surface triangulation is modified in accordance to a size map. The latter can be either the intrinsic size map (computed automatically and based on the surface properties, i.e. the local curvatures), or on a given size map (which is then combined to the intrinsic size map). One should use this option to coarsen the mesh, when a regular mesh for computation purposes is desired, i.e. a mesh with good aspect ratios or good quality elements. - - - Mesh for finite element computation : Coarsening (-1) - - - - - - 17 - 228 - 585 - 22 - - - - The given surface triangulation is modfied in accordance to a size map. + + + Mesh for finite element computation : Coarsening (-1) + + + + + + + The given surface triangulation is modified in accordance to a size map. The latter can be either the intrinsic size map (computed automatically and based on the surface properties, i.e. the local curvatures), or on a given size map (which is then combined to the intrinsic size map). One should use this option to coarsen and enrich the mesh, when a regular mesh for computation purposes is desired, i.e. a mesh with good aspect ratios or good quality elements - - - Mesh for finite element computation : Coarsening and Enrichment (1) - - - + + + Mesh for finite element computation : Coarsening and Enrichment (1) + + + + + + + + + + - + 10 - 20 - 871 - 161 + 420 + 750 + 70 - - - 10 - + + This parameter enables the user to bound the maximal chordal deviation allowed, +that is the maximal distance allowed between the detected curve and the plane P +of the corresponding mesh face. +In other words, it avoids having faces too far away from the curve they should represent. - Original Mesh + Chordal deviation Tolerance - + - 10 + 40 30 - 861 - 101 + 110 + 24 - - - - - - 10 - false - - - - QFrame::Box - - - Smesh mesh - - - false - - - 0 - - - - - - - - - - - ../../../../../../../../SalomeSrc/SMESH_V6_main/src/Tools/YamsPlug/open.png../../../../../../../../SalomeSrc/SMESH_V6_main/src/Tools/YamsPlug/open.png - - - - 18 - 18 - - - - false - - - - - - - - 10 - - - - - - - - or - - - - - - - - 10 - - - - Mesh File (GMF format) - - - - - - - - 10 - - - - - + + If the Units parameter is relative, epsilon max correspond to (per thousand) s*Tolerance/1000, where s is the size of the bounding box of the domain. +If the Units parameter is absolute, the tolerance parameter is expressed in model units: + if P=2 and point coordinates are given in millimeters, the maximal chordal deviation is 2 mm. + + + + + + 220 + 30 + 120 + 24 + + + + Values are expressed in the model units. + + + Absolute units + + + false + + + + + + 350 + 30 + 120 + 24 + + + + Values are relative (per thousand) to the bounding box size. + + + Relative units + + + true + - + - 430 - 540 - 81 - 31 + 10 + 10 + 750 + 120 - PreferDefault + 10 - - true - - - <html><head/><body><p>If the Units parameter is relative, epsilon max corresponds to 0.001x s x tolerance parameter where s is the size of the bounding box of the domain.</p><p>If the Units parameter (P) is absolute, the tolerance parameter is expressed in model units :</p><p>if P=2 and point coordinates are given in millimetre, it means that the maximal chordal deviation is 2 mm </p></body></html> - - - 0 - - - 1.000000000000000 - - - 1000.000000000000000 - - - 1.000000000000000 - - - 10.000000000000000 - - - - - - 30 - 500 - 801 - 37 - - - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> -<table border="0" style="-qt-table-type: root; margin-top:4px; margin-bottom:4px; margin-left:4px; margin-right:4px;"> -<tr> -<td style="border: none;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p></td></tr></table></body></html> - - - Units - - - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> -<table border="0" style="-qt-table-type: root; margin-top:4px; margin-bottom:4px; margin-left:4px; margin-right:4px;"> -<tr> -<td style="border: none;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Set chordal deviation tolerance:</p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">This parameter enables the user to bound the maximal chordal deviation allowed,</p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">that is, the maximal distance allowed between the detected curve and the plane P</p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">of the corresponding mesh face.</p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">In other words, it avoids having faces too far away from the curve </p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">they represent (or should represent).</p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p></td></tr></table></body></html> - - - Chordal deviation Tolerance - - - - - - - - - 60 - 540 - 230 - 31 - - - - - - - Values are expressed in the model units. - - - Absolute - - - false - - - - - - - Values are relative to the bounding box size. - - - Relative - - - true - - - - - - - - - 520 - 540 - 301 - 51 - - - - <html><head/><body><p><span style=" font-size:8pt;">0/00 if relative</span></p><p><span style=" font-size:8pt;">Mesh unit if absolute</span></p></body></html> + + Original Mesh + + + + 40 + 70 + 190 + 31 + + + + + 10 + + + + Mesh File GMF format + + + + 18 + 18 + + + + + + + 240 + 70 + 481 + 31 + + + + + 10 + + + + + + + 40 + 30 + 190 + 31 + + + + Mesh Object Browser + + + + 18 + 18 + + + + false + + + + + + 240 + 30 + 481 + 31 + + + + + 10 + + + + + + + 10 + 80 + 31 + 18 + + + + or + + - layoutWidget - layoutWidget groupBox GBOptim - SP_Tolerance - label_11 - Advanced Remeshing Options + Advanced Remeshing Options - + 10 10 - 761 - 71 + 750 + 120 - You can disable : + You can set/unset - 100 + 30 20 271 - 23 + 25 - if not set (ridge detection disabled), Yams will not try to detect any new ridge edge by its own mechanism : + If not set (ridge detection disabled), Yams will not try to detect any new ridge edge by its own mechanism : it will consider as ridge only the ridges given in the mesh. -All non-ridge edges that would have been detected as ridge by the Ridge angle paramaeter +All non-ridge edges that would have been detected as ridge by the ridge angle parameter (see below) will be considered as part of the same continuous patch. This option should not be checked when all the known ridges of the mesh are given and when all other possible ridges are not geometric ridges to take into account. @@ -613,10 +543,10 @@ when all other possible ridges are not geometric ridges to take into account. - 100 - 40 + 30 + 50 271 - 23 + 25 @@ -631,127 +561,159 @@ or add vertices (refines) to change the mesh. true + + + + + 30 + 80 + 271 + 25 + + + + If set, Yams creates new vertices placed on the curved surface and adds them to elements. +It means one extra vertex on edge (P2 or quadratic triangles). +New created vertices are saved in the .mesh file under keyword section 'Vertices' + + + split edge + + + false + + + + 10 - 90 - 841 - 391 + 140 + 750 + 270 - You can control + You can control +##1 - 10 + 30 30 - 91 - 23 + 100 + 25 - 0.890000000000000 + 0.89 - 0.010000000000000 + 0.01 - 0.040000000000000 + 0.04 - 120 - 20 - 731 - 61 + 140 + 30 + 630 + 30 This field (as well as tolerance) enables the user to control the accuracy of the piecewise linear approximation of the surface. This parameter enables the user to -control the maximal angle allowed between two adjacent faces. It can be used to +control the maximal angle allowed between two adjacent faces. It can be used to bound the maximal deviation of the mesh faces from the tangent planes at mesh vertices. In other words, it avoids having sharp angles between faces representing a smooth curve. This parameter enables the user to specify the maximal chordal deviation "max relatively to the curvature. Following that criterion: -- if the chordal deviation epsilon is smaller than epsilon max *r, it is acceptable to remove the considered point; +- if the chordal deviation epsilon is smaller than epsilon max*r, it is acceptable to remove the considered point; - if the chordal deviation epsilon is greater than epsiolon max*r, the considered mesh face should be redefined -by adding a point on the curve. + by adding a point on the curve. One can see that the smaller the radius r, the harder it is to satisfy this criterion: epsilon max is a real value corresponding to a percentage, the ratio between the chordal deviation to the local curvature. This field is used only for optimisation style -O values of -1, 0 and 1. The default value for "max is set to 0:04 which leads to angles of less than 33 degrees between two adjacent -faces . +faces. - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<table border="0" style="-qt-table-type: root; margin-top:4px; margin-bottom:4px; margin-left:4px; margin-right:4px;"> -<tr> -<td style="border: none;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Geometrical approximation : Maximum angle (1-cos(angle)) allowed </span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">between a face and a curve </span><span style=" font-family:'Sans Serif'; font-size:8pt;">(not separated by a ridge).</span><span style=" font-family:'Sans Serif';">)</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif';"><br /></p></td></tr></table></body></html> + Geometrical approximation: +Maximum angle allowed between a face and a curve (not separated by a ridge). + + +##2 + + + + 30 + 70 + 100 + 25 + + + + 90. + + + 45. - 120 - 80 - 691 - 71 + 140 + 70 + 630 + 30 - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> -<table border="0" style="-qt-table-type: root; margin-top:4px; margin-bottom:4px; margin-left:4px; margin-right:4px;"> -<tr> -<td style="border: none;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">Ridge angle:</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">if the angle between the normal vectors of two adjacent faces</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Sans Serif';">exceeds this value, the edge common to the faces is a ridge</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif';"><br /></p></td></tr></table></body></html> + If the angle between the normal vectors of two adjacent faces exceeds this value, +the edge common to the faces is a ridge. - +##3 + - 10 - 100 - 91 - 23 + 30 + 110 + 100 + 25 + + 0.01 + - 90.000000000000000 + 100. + + + 0.1 - 45.000000000000000 + 100. - 120 - 160 - 681 - 61 + 140 + 110 + 630 + 30 - This parameter allows the user to prescribe a maximal size hmax + This parameter allows the user to prescribe a maximal size hmax for the mesh elements i.e., the lengths of the edges with respect to the specified size map. The corresponding values are either relative or absolute depending on the choosen parameter. The default values are automatically set based on the surface geometry (curvature dependent) and its @@ -760,97 +722,44 @@ Please note that, as it is not strictly possible to obey the given or computed s size may be slightly bigger than the prescribed ones. - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans Serif'; font-size:10pt; font-weight:400; font-style:normal;"> -<table border="0" style="-qt-table-type: root; margin-top:4px; margin-bottom:4px; margin-left:4px; margin-right:4px;"> -<tr> -<td style="border: none;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Maximal size allowed around vertices:</p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">the lengths of the edges with respect to the specified size map.</p></td></tr></table></body></html> - - - - - - 120 - 290 - 691 - 91 - - - - This parameter enables the user to control the element size variation in the triangulation. -Yams will avoid getting two adjacent edges which sizes differ by a factor bigger than this parameter. -To avoid rapid size variations, a size correction procedure is applied to the size map. -In other words: if two adjacent edges are respectively e1 and e2 long -if e2 > parameter * e1 then e02 the new size for the second edge will be set to parameter* e1. -This procedure is de-activated if yams computes a mesh for finite element with only coarsening. -The default value is 1.3, which is the usual value set for computational meshes. - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans Serif'; font-size:10pt; font-weight:400; font-style:normal;"> -<table border="0" style="-qt-table-type: root; margin-top:4px; margin-bottom:4px; margin-left:4px; margin-right:4px;"> -<tr> -<td style="border: none;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Mesh Gradation ie the element size variation in the triangulation:</p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Yams will avoid having two adjacent edges which sizes </p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">vary more than the given gradation.</p></td></tr></table></body></html> - - - - - - 10 - 300 - 91 - 23 - - - - 0.010000000000000 - - - 1.300000000000000 + Maximal size allowed around vertices, +the lengths of the edges with respect to the specified size map. - +##4 + - 10 - 170 - 91 - 23 + 30 + 150 + 100 + 25 - 0.010000000000000 + 0. - 100.000000000000000 + 100. - 0.100000000000000 + 0.1 - 100.000000000000000 + 5. - 120 - 230 - 661 - 51 + 140 + 150 + 630 + 30 - This parameter allows the user to prescribe a maximal size hmax + This parameter allows the user to prescribe a maximal size hmax for the mesh elements i.e., the lengths of the edges with respect to the specified size map. The corresponding values are either relative or absolute depending on the choosen parameter. The default values are automatically set based on the surface geometry (curvature dependent) and its @@ -859,73 +768,50 @@ Please note that, as it is not strictly possible to obey the given or computed s size may be slightly bigger than the prescribed ones. - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans Serif'; font-size:10pt; font-weight:400; font-style:normal;"> -<table border="0" style="-qt-table-type: root; margin-top:4px; margin-bottom:4px; margin-left:4px; margin-right:4px;"> -<tr> -<td style="border: none;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Minimal size allowed around vertices:</p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">the lengths of the edges with respect to the specified size map.</p></td></tr></table></body></html> + Minimal size allowed around vertices, +the lengths of the edges with respect to the specified size map. - +##5 + - 10 - 230 - 91 - 23 + 30 + 190 + 100 + 25 - - 0.000000000000000 - - - 100.000000000000000 - - 0.100000000000000 + 0.01 - 5.000000000000000 + 1.3 + + + + + + 140 + 190 + 630 + 30 + + + + This parameter enables the user to control the element size variation in the triangulation. +Yams will avoid getting two adjacent edges which sizes differ by a factor bigger than this parameter. +To avoid rapid size variations, a size correction procedure is applied to the size map. +In other words: if two adjacent edges are respectively e1 and e2 long +if e2 > parameter * e1 then e02 the new size for the second edge will be set to parameter* e1. +This procedure is de-activated if yams computes a mesh for finite element with only coarsening. +The default value is 1.3, which is the usual value set for computational meshes. + + + Mesh Gradation: the element size variation in the triangulation. +Yams will avoid having two adjacent edges which sizes vary more than the given gradation. - - - - - 20 - 490 - 751 - 31 - - - - You can enable : - - - - - - 70 - 530 - 271 - 23 - - - - if set, Yams creates new vertices placed on the curved surface and adds them to elements. -It means one extra vertex on edge (P2 or quadratic triangles). -New created vertices are saved in the .mesh file under keyword section Vertices - - - split edge - - - false - @@ -936,101 +822,80 @@ New created vertices are saved in the .mesh file under keyword section Vertices 10 - 30 - 741 - 131 + 10 + 750 + 130 Yams Generic Options - + + - 40 + 20 30 - 441 - 34 + 100 + 25 - - - - - Verbosity Level - - - - - - - Qt::Horizontal - - - - 28 - 20 - - - - - - 10 - 7 + 3 - - - - + + - 40 - 70 - 441 - 34 + 130 + 30 + 600 + 30 - - - - - - 225 - 25 - - + + sets the verbosity level. +From 0 (no detail) to 10 (very detailed). +Default is 3. + - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans Serif'; font-size:10pt; font-weight:400; font-style:normal;"> -<table border="0" style="-qt-table-type: root; margin-top:4px; margin-bottom:4px; margin-left:4px; margin-right:4px;"> -<tr> -<td style="border: none;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Memory size (in Mbytes)</p></td></tr></table></body></html> + Verbosity level - - - - - Qt::Horizontal + + + + + 20 + 70 + 100 + 25 + + + + 100000 - - - 28 - 20 - + + 0 + + + + + + + 130 + 70 + 600 + 30 + + + + Memory size (in Mbytes) - - - - The program requires roughly about 370 bytes per point. It is thus possible to estimate a priori the required memory size to complete a job. As an example of memory space needed, a mesh @@ -1041,33 +906,25 @@ The memory needed for mesh modification is allocated dynamically at the beginnin memory allowed, it will stop inserting points and, if possible, the current mesh will be saved as it is, valid and conformal, provided the input mesh was valid and conformal. Specify the memory if: -- the automatically allocated memory reveals insufficient when the user asked to enrich the given mesh; +- the automatically allocated memory reveals insufficient when the user asked to enrich the given mesh. - you want to limit the amount of memory used by the program. If the input mesh size requires more memory than requested or if the allocated memory (user defined or not) exceeds the machine capabilities, the tool will stop because of insufficient memory. - - 100000 - - - 0 - - - - + 10 - 230 - 741 - 141 + 150 + 750 + 170 - Plug-In Generic Options + Plug-in Generic Options @@ -1079,7 +936,7 @@ exceeds the machine capabilities, the tool will stop because of insufficient mem - File used to save Yams Params : + File used to save Yams hypothesis parameters : @@ -1094,10 +951,6 @@ exceeds the machine capabilities, the tool will stop because of insufficient mem - - - ../../../../../../../../SalomeSrc/SMESH_V6_main/src/Tools/YamsPlug/open.png../../../../../../../../SalomeSrc/SMESH_V6_main/src/Tools/YamsPlug/open.png - @@ -1109,6 +962,47 @@ exceeds the machine capabilities, the tool will stop because of insufficient mem + + + + + 20 + 110 + 70 + 31 + + + + Save + + + + 18 + 18 + + + + + + + + 120 + 110 + 70 + 31 + + + + Load + + + + 18 + 18 + + + + diff --git a/src/Tools/YamsPlug/doc/Generics_params.rst b/src/Tools/YamsPlug/doc/Generics_params.rst index 32b31b1ac..046e688c9 100644 --- a/src/Tools/YamsPlug/doc/Generics_params.rst +++ b/src/Tools/YamsPlug/doc/Generics_params.rst @@ -15,7 +15,7 @@ You usually don't have to set this parameter but you can choose to limit the amo - **File** -You can change the file used to store the remeshing hypothesis. see paragraph :ref:`hypothesis-label` for further informations. +You can change the file used to store remeshing hypotheses. see paragraph :ref:`hypothesis-label` for further informations. .. image:: images/Generic.png :align: center diff --git a/src/Tools/YamsPlug/doc/Makefile.am b/src/Tools/YamsPlug/doc/Makefile.am index d32f6589d..2841defc7 100644 --- a/src/Tools/YamsPlug/doc/Makefile.am +++ b/src/Tools/YamsPlug/doc/Makefile.am @@ -12,7 +12,7 @@ RSTFILES = lct.rst \ Generics_params.rst \ Advanced_params.rst -EXTRA_DIST += $(RSTFILES) images +EXTRA_DIST += $(RSTFILES) images files # You can set these variables from the command line. SPHINXOPTS = diff --git a/src/Tools/YamsPlug/doc/Mandatory_params.rst b/src/Tools/YamsPlug/doc/Mandatory_params.rst index c752c692b..f657c1d92 100644 --- a/src/Tools/YamsPlug/doc/Mandatory_params.rst +++ b/src/Tools/YamsPlug/doc/Mandatory_params.rst @@ -61,7 +61,7 @@ This is the main remeshing Option. Yams always does quality improvement. It is - **Mesh for finite element computation : Coarsening** - The given surface triangulation is modfied in accordance to a size map. The latter is the intrinsic size map (computed automatically and based on the surface properties, i.e. the local curvatures). One should use this option to coarsen the mesh, when a regular mesh for computation purposes is desired, i.e. a mesh with good aspect ratios or good quality elements. + The given surface triangulation is modified in accordance to a size map. The latter is the intrinsic size map (computed automatically and based on the surface properties, i.e. the local curvatures). One should use this option to coarsen the mesh, when a regular mesh for computation purposes is desired, i.e. a mesh with good aspect ratios or good quality elements. It is equivalent to Yams's batch option -1. diff --git a/src/Tools/YamsPlug/doc/editHypo.rst b/src/Tools/YamsPlug/doc/editHypo.rst index 414d8ad0d..75b8eb76a 100644 --- a/src/Tools/YamsPlug/doc/editHypo.rst +++ b/src/Tools/YamsPlug/doc/editHypo.rst @@ -4,17 +4,23 @@ How to save Yams Parameters =========================== -As Yams hypothesis are not meshing hypothesis for Salome (but hypothesis for yams), parameters -are stored in a special file. Default file is $HOME/.yams.dat. It is strongly recommended that you -change this name if you want to preserve the way you obtain a mesh : This file is never cleaned. -All sets of parameters are logged in it. +Yams hypothesis is not meshing hypothesis for Salome, but hypothesis for yams. +The current set of parameters is automatically written in the salome study object browser when you run computation. +Theses parameters could also be stored in a special file. +Default file is $HOME/.yams.dat. +This ASCII file is appended, and never cleaned. -- To save the current setting, click on "Save Params" pushbutton. -- A set of parameters is automatically written in the .yams.dat file when you run computation. -- Restoring the default settings can be done by pushing "Default Params". -- "Loading Params" will reload the last set of parameters +In frame "Plug-in Generic Options": +- To save the current setting in this file, click on "Save" pushbutton. +- To load the last set of parameters saved, click on "Load" pushbutton. + +At the bottom of the dialog window: + +- To save a current setting in the study object browser, click on "Save" pushbutton. +- To load a current setting from the study object browser, click on "Load" pushbutton. +- To load the default setting, click on "Default" pushbutton. . **example of .yams.dat** @@ -22,39 +28,25 @@ All sets of parameters are logged in it. .. code-block:: python - # Save intermediate params - # Params for mesh : - Optimisation ='Quality improvement Only (0)' - Units ='Relative' - Chordal_Tolerance_Deviation=1.0 - Ridge_Detection=True - Split_Edge=False - Point_Smoothing=True - Geometrical_Approximation=0.04 - Ridge_Angle=45.0 - Maximum_Size=-2.0 - Minimum_Size=-2.0 - Mesh_Gradation=1.3 - Verbosity=3 - Memory=0 - - - - # Params for Hypothese : monHypo_Yams_0 + # YAMS hypothesis parameters # Params for mesh : Mesh_1 - Optimisation ='Quality improvement Only (0)' - Units ='Relative' - Chordal_Tolerance_Deviation=1.0 - Ridge_Detection=True - Split_Edge=False - Point_Smoothing=True - Geometrical_Approximation=0.04 - Ridge_Angle=45.0 - Maximum_Size=-2.0 - Minimum_Size=-2.0 - Mesh_Gradation=1.3 + # Date : 23/05/13 14:23:18 + # Command : yams -v 3 -O 0 -Drelative,tolerance=0.100000,maxsize=0.010000,minsize=0.000000 /tmp/ForYams_1.mesh + Optimisation=Quality improvement Only (0) + Units=Relative + ChordalToleranceDeviation=0.1 + RidgeDetection=True + SplitEdge=False + PointSmoothing=True + GeometricalApproximation=0.04 + RidgeAngle=45.0 + MaximumSize=0.01 + MinimumSize=0.0 + MeshGradation=1.3 Verbosity=3 Memory=0 + + diff --git a/src/Tools/YamsPlug/doc/files/YamsWhitePaper_3.2.pdf b/src/Tools/YamsPlug/doc/files/YamsWhitePaper_3.2.pdf new file mode 100644 index 000000000..f445bba28 Binary files /dev/null and b/src/Tools/YamsPlug/doc/files/YamsWhitePaper_3.2.pdf differ diff --git a/src/Tools/YamsPlug/doc/images/Advanced.png b/src/Tools/YamsPlug/doc/images/Advanced.png index bd91a1733..eb8ee0fb0 100644 Binary files a/src/Tools/YamsPlug/doc/images/Advanced.png and b/src/Tools/YamsPlug/doc/images/Advanced.png differ diff --git a/src/Tools/YamsPlug/doc/images/AppelYams.png b/src/Tools/YamsPlug/doc/images/AppelYams.png index a18b9ef65..d3f6fddc6 100644 Binary files a/src/Tools/YamsPlug/doc/images/AppelYams.png and b/src/Tools/YamsPlug/doc/images/AppelYams.png differ diff --git a/src/Tools/YamsPlug/doc/images/Generic.png b/src/Tools/YamsPlug/doc/images/Generic.png index fb37ab42c..eaabb4c92 100644 Binary files a/src/Tools/YamsPlug/doc/images/Generic.png and b/src/Tools/YamsPlug/doc/images/Generic.png differ diff --git a/src/Tools/YamsPlug/doc/images/Simple.png b/src/Tools/YamsPlug/doc/images/Simple.png index 98cf1b9b9..63f61b421 100644 Binary files a/src/Tools/YamsPlug/doc/images/Simple.png and b/src/Tools/YamsPlug/doc/images/Simple.png differ diff --git a/src/Tools/YamsPlug/doc/index.rst b/src/Tools/YamsPlug/doc/index.rst index 864044638..45442f9ae 100644 --- a/src/Tools/YamsPlug/doc/index.rst +++ b/src/Tools/YamsPlug/doc/index.rst @@ -11,6 +11,8 @@ Mesh module for remeshing 2D Surface. Yams plug-in uses Distene commercial software Yams, which is an **automatic surface remeshing tool**. This plug_in offers only the most common functionnalities of the tool. +.. note:: + for a complete documentation, see :download:`Yams whitepaper `. Contents: @@ -19,8 +21,8 @@ Contents: lct.rst Mandatory_params.rst - Generics_params.rst Advanced_params.rst + Generics_params.rst editHypo.rst diff --git a/src/Tools/YamsPlug/doc/lct.rst b/src/Tools/YamsPlug/doc/lct.rst index 6f3bc515b..c26492602 100644 --- a/src/Tools/YamsPlug/doc/lct.rst +++ b/src/Tools/YamsPlug/doc/lct.rst @@ -1,7 +1,7 @@ Running Yams Plug-in ===================== -Yamms plug-in can be invoked via SMESH Plugin item in Mesh menu bar +Yams plug-in can be invoked via SMESH Plugin item in Mesh menu bar .. image:: images/AppelYams.png :align: center diff --git a/src/Tools/YamsPlug/monViewText.py b/src/Tools/YamsPlug/monViewText.py index a613f5d6b..ce291033b 100644 --- a/src/Tools/YamsPlug/monViewText.py +++ b/src/Tools/YamsPlug/monViewText.py @@ -1,4 +1,4 @@ -# -*- coding: iso-8859-1 -*- +# -*- coding: utf-8 -*- # Copyright (C) 2007-2013 EDF R&D # # This library is free software; you can redistribute it and/or @@ -28,45 +28,59 @@ from PyQt4.QtCore import * # Import des panels -# ------------------------------- # from ViewText import Ui_ViewExe -class MonViewText(Ui_ViewExe,QDialog): -# ------------------------------- # + +class MonViewText(Ui_ViewExe, QDialog): """ Classe permettant la visualisation de texte """ - def __init__(self,parent,txt): + def __init__(self, parent, txt): QDialog.__init__(self,parent) - self.pere=parent self.setupUi(self) - self.resize( QSize(600,600).expandedTo(self.minimumSizeHint()) ) - self.connect( self.PB_Ok,SIGNAL("clicked()"), self, SLOT("close()") ) + self.resize( QSize(1000,600).expandedTo(self.minimumSizeHint()) ) + #self.connect( self.PB_Ok,SIGNAL("clicked()"), self, SLOT("close()") ) + self.connect( self.PB_Ok,SIGNAL("clicked()"), self.theClose ) self.connect( self.PB_Save,SIGNAL("clicked()"), self.saveFile ) self.monExe=QProcess(self) - self.connect(self.monExe, SIGNAL("readyReadStandardOutput()"), self.readFromStdOut ) self.connect(self.monExe, SIGNAL("readyReadStandardError()"), self.readFromStdErr ) - self.connect(self.monExe, SIGNAL("finished(int )"), self.exeFinished ) # Je n arrive pas a utiliser le setEnvironment du QProcess # fonctionne hors Salome mais pas dans Salome ??? - LICENCE=os.environ['DISTENE_LICENCE_FILE_FOR_YAMS'] - txt='export DISTENE_LICENSE_FILE='+LICENCE+';'+ txt + cmds='' + try : + LICENCE_FILE=os.environ["DISTENE_LICENCE_FILE_FOR_YAMS"] + except: + LICENCE_FILE='' + try : + PATH=os.environ["DISTENE_PATH_FOR_YAMS"] + except: + PATH='' + if LICENCE_FILE != '': + cmds+='source '+LICENCE_FILE+'\n' + else: + cmds+="# $DISTENE_LICENCE_FILE_FOR_YAMS NOT SET\n" + if PATH != '': + cmds+='export PATH='+PATH+':$PATH\n' + else: + cmds+="# $DISTENE_PATH_FOR_YAMS NOT SET\n" + #cmds+='env\n' + cmds+='rm -f '+self.parent().fichierOut+'\n' + cmds+=txt+'\n' + cmds+='echo END_OF_Yams\n' pid=self.monExe.pid() - nomFichier='/tmp/yam_'+str(pid)+'.py' + nomFichier='/tmp/Yams_'+str(pid)+'.sh' f=open(nomFichier,'w') - f.write(txt) + f.write(cmds) f.close() maBidouille='sh ' + nomFichier self.monExe.start(maBidouille) self.monExe.closeWriteChannel() + self.enregistreResultatsDone=False self.show() - def exeFinished(self): - self.pere.enregistreResultat() - def saveFile(self): #recuperation du nom du fichier savedir=os.environ['HOME'] @@ -84,8 +98,19 @@ class MonViewText(Ui_ViewExe,QDialog): def readFromStdErr(self): a=self.monExe.readAllStandardError() - self.TB_Exe.append(QString.fromUtf8(a.data(),len(a))) ; + self.TB_Exe.append(QString.fromUtf8(a.data(),len(a))) def readFromStdOut(self) : a=self.monExe.readAllStandardOutput() - self.TB_Exe.append(QString.fromUtf8(a.data(),len(a))) ; + aa=QString.fromUtf8(a.data(),len(a)) + self.TB_Exe.append(aa) + if "END_OF_Yams" in aa: + self.parent().enregistreResultat() + self.enregistreResultatsDone=True + #self.theClose() + + def theClose(self): + if not self.enregistreResultatsDone: + self.parent().enregistreResultat() + self.enregistreResultatsDone=True + self.close() diff --git a/src/Tools/YamsPlug/monYamsPlugDialog.py b/src/Tools/YamsPlug/monYamsPlugDialog.py index 1e9c32fc9..6e6088c11 100644 --- a/src/Tools/YamsPlug/monYamsPlugDialog.py +++ b/src/Tools/YamsPlug/monYamsPlugDialog.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright (C) 2007-2013 EDF R&D +# Copyright (C) 2007-2013 EDF R&D # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -17,6 +17,7 @@ # # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # Modules Python # Modules Eficas @@ -31,275 +32,463 @@ class MonYamsPlugDialog(Ui_YamsPlugDialog,QWidget): """ """ def __init__(self): - QWidget.__init__(self) - self.setupUi(self) - self.connecterSignaux() - self.fichierIn="" - self.fichierOut="" - self.MeshIn="" - self.num=1 - -# Ces parametres ne sont pas remis à rien par le clean - self.paramsFile= os.path.abspath(os.path.join(os.environ['HOME'],'.yams.dat')) - self.LE_ParamsFile.setText(self.paramsFile) - self.LE_MeshFile.setText("") - self.LE_MeshSmesh.setText("") + QWidget.__init__(self) + self.setupUi(self) + self.connecterSignaux() + self.fichierIn="" + self.fichierOut="" + self.MeshIn="" + self.commande="" + self.num=1 + self.__selectedMesh=None + + # complex whith QResources: not used + # The icon are supposed to be located in the $SMESH_ROOT_DIR/share/salome/resources/smesh folder, + # other solution could be in the same folder than this python module file: + # iconfolder=os.path.dirname(os.path.abspath(__file__)) + + self.iconfolder=os.environ["SMESH_ROOT_DIR"]+"/share/salome/resources/smesh" + #print "monYamsPlugDialog iconfolder",iconfolder + icon = QIcon() + icon.addFile(os.path.join(self.iconfolder,"select1.png")) + self.PB_LoadHyp.setIcon(icon) + self.PB_LoadHyp.setToolTip("hypothesis from Salome Object Browser") + self.PB_SaveHyp.setIcon(icon) + self.PB_SaveHyp.setToolTip("hypothesis to Salome Object Browser") + self.PB_MeshSmesh.setIcon(icon) + self.PB_MeshSmesh.setToolTip("source mesh from Salome Object Browser") + icon = QIcon() + icon.addFile(os.path.join(self.iconfolder,"open.png")) + self.PB_ParamsFileExplorer.setIcon(icon) + self.PB_Load.setIcon(icon) + self.PB_Load.setToolTip("hypothesis from file") + self.PB_Save.setIcon(icon) + self.PB_Save.setToolTip("hypothesis to file") + self.PB_MeshFile.setIcon(icon) + self.PB_MeshFile.setToolTip("source mesh from a file in disk") + + #Ces parametres ne sont pas remis à rien par le clean + self.paramsFile= os.path.abspath(os.path.join(os.environ["HOME"],".yams.dat")) + self.LE_ParamsFile.setText(self.paramsFile) + self.LE_MeshFile.setText("") + self.LE_MeshSmesh.setText("") + + v1=QDoubleValidator(self) + v1.setBottom(0.) + #v1.setTop(1000.) #per thousand... only if relative + v1.setDecimals(2) + self.SP_Tolerance.setValidator(v1) + self.SP_Tolerance.titleForWarning="Chordal Tolerance" + + self.resize(800, 600) + self.clean() def connecterSignaux(self) : - self.connect(self.PB_Cancel,SIGNAL("clicked()"),self.PBCancelPressed) - self.connect(self.PB_Default,SIGNAL("clicked()"),self.clean) - self.connect(self.PB_Help,SIGNAL("clicked()"),self.PBHelpPressed) - self.connect(self.PB_Load,SIGNAL("clicked()"),self.PBLoadPressed) - self.connect(self.PB_OK,SIGNAL("clicked()"),self.PBOKPressed) - self.connect(self.PB_Save,SIGNAL("clicked()"),self.PBSavePressed) - self.connect(self.PB_MeshFile,SIGNAL("clicked()"),self.PBMeshFilePressed) - self.connect(self.PB_MeshSmesh,SIGNAL("clicked()"),self.PBMeshSmeshPressed) - self.connect(self.PB_ParamsFileExplorer,SIGNAL("clicked()"),self.setParamsFileName) - self.connect(self.LE_MeshFile,SIGNAL("returnPressed()"),self.meshFileNameChanged) - self.connect(self.LE_ParamsFile,SIGNAL("returnPressed()"),self.paramsFileNameChanged) - + self.connect(self.PB_Cancel,SIGNAL("clicked()"),self.PBCancelPressed) + self.connect(self.PB_Default,SIGNAL("clicked()"),self.clean) + self.connect(self.PB_Help,SIGNAL("clicked()"),self.PBHelpPressed) + self.connect(self.PB_OK,SIGNAL("clicked()"),self.PBOKPressed) + + self.connect(self.PB_Load,SIGNAL("clicked()"),self.PBLoadPressed) + self.connect(self.PB_Save,SIGNAL("clicked()"),self.PBSavePressed) + self.connect(self.PB_LoadHyp,SIGNAL("clicked()"),self.PBLoadHypPressed) + self.connect(self.PB_SaveHyp,SIGNAL("clicked()"),self.PBSaveHypPressed) + + self.connect(self.PB_MeshFile,SIGNAL("clicked()"),self.PBMeshFilePressed) + self.connect(self.PB_MeshSmesh,SIGNAL("clicked()"),self.PBMeshSmeshPressed) + self.connect(self.LE_MeshSmesh,SIGNAL("returnPressed()"),self.meshSmeshNameChanged) + self.connect(self.PB_ParamsFileExplorer,SIGNAL("clicked()"),self.setParamsFileName) + self.connect(self.LE_MeshFile,SIGNAL("returnPressed()"),self.meshFileNameChanged) + self.connect(self.LE_ParamsFile,SIGNAL("returnPressed()"),self.paramsFileNameChanged) def PBHelpPressed(self): - try : - maDoc=os.environ['DISTENE_YAMS_DOC_PDF'] - except Exception: - QMessageBox.warning( self, "Help unavailable", str(maDoc) + " not found") - command="xdg-open "+maDoc+";" - subprocess.call(command, shell=True) - + try : + mydir=os.environ["SMESH_ROOT_DIR"] + except Exception: + QMessageBox.warning(self, "Help", "Help unavailable $SMESH_ROOT_DIR not found") + return + maDoc=mydir+"/share/doc/salome/gui/SMESH/yams/_downloads/YamsWhitePaper_3.2.pdf" + command="xdg-open "+maDoc+";" + subprocess.call(command, shell=True) def PBOKPressed(self): - if not(self.PrepareLigneCommande()) : return - self.PBSavePressed(NomHypo=True) - maFenetre=MonViewText(self,self.commande) + if not(self.PrepareLigneCommande()): + #warning done yet + #QMessageBox.warning(self, "Compute", "Command not found") + return + maFenetre=MonViewText(self,self.commande) def enregistreResultat(self): - if not(os.path.isfile(self.fichierOut)) : return - import smesh - import SMESH - import salome - from salome.kernel import studyedit - - maStudy=studyedit.getActiveStudy() - smesh.SetCurrentStudy(maStudy) - (outputMesh, status) = smesh.CreateMeshesFromGMF(self.fichierOut) - meshname = 'yams'+str(self.num) - smesh.SetName(outputMesh.GetMesh(), meshname) - outputMesh.Compute() - - - self.editor = studyedit.getStudyEditor() # - moduleEntry=self.editor.findOrCreateComponent("SMESH","SMESH") - HypReMeshEntry = self.editor.findOrCreateItem( moduleEntry, name = 'HypoForRemesh', - comment = 'HypoForRemshing') - monStudyBuilder=maStudy.NewBuilder(); - monStudyBuilder.NewCommand(); - newStudyIter=monStudyBuilder.NewObject(HypReMeshEntry) - aNameAttrib=monStudyBuilder.FindOrCreateAttribute(newStudyIter,"AttributeName") - hypoName = 'monHypo_Yams_'+str(self.num) - aNameAttrib.SetValue(hypoName) - aCommentAttrib=monStudyBuilder.FindOrCreateAttribute(newStudyIter,"AttributeComment") - aCommentAttrib.SetValue(str(self.commande)) - - SOMesh=maStudy.FindObjectByName(meshname ,"SMESH")[0] - newLink=monStudyBuilder.NewObject(SOMesh) - monStudyBuilder.Addreference(newLink, newStudyIter); - if salome.sg.hasDesktop(): salome.sg.updateObjBrowser(0) - self.num+=1 - return True + import smesh + import SMESH + import salome + from salome.kernel import studyedit + + if not os.path.isfile(self.fichierOut): + QMessageBox.warning(self, "Compute", "Result file "+self.fichierOut+" not found") + + maStudy=studyedit.getActiveStudy() + smesh.SetCurrentStudy(maStudy) + (outputMesh, status) = smesh.CreateMeshesFromGMF(self.fichierOut) + name=str(self.LE_MeshSmesh.text()) + initialMeshFile=None + initialMeshObject=None + if name=="": + a=str(self.fichierIn) + name=os.path.basename(os.path.splitext(a)[0]) + initialMeshFile=a + else: + initialMeshObject=maStudy.FindObjectByName(name ,"SMESH")[0] + + meshname = name+"_YAMS_"+str(self.num) + smesh.SetName(outputMesh.GetMesh(), meshname) + outputMesh.Compute() #no algorithms message for "Mesh_x" has been computed with warnings: - global 1D algorithm is missing + + self.editor = studyedit.getStudyEditor() # + moduleEntry=self.editor.findOrCreateComponent("SMESH","SMESH") + HypReMeshEntry = self.editor.findOrCreateItem( + moduleEntry, name = "Plugins Hypotheses", icon="mesh_tree_hypo.png") #, comment = "HypoForRemeshing" ) + + monStudyBuilder=maStudy.NewBuilder() + monStudyBuilder.NewCommand() + newStudyIter=monStudyBuilder.NewObject(HypReMeshEntry) + self.editor.setAttributeValue(newStudyIter, "AttributeName", "YAMS Parameters_"+str(self.num)) + self.editor.setAttributeValue(newStudyIter, "AttributeComment", self.getResumeData(separator=" ; ")) + + SOMesh=maStudy.FindObjectByName(meshname ,"SMESH")[0] + + if initialMeshFile!=None: + newStudyFileName=monStudyBuilder.NewObject(SOMesh) + self.editor.setAttributeValue(newStudyFileName, "AttributeName", "meshFile") + self.editor.setAttributeValue(newStudyFileName, "AttributeExternalFileDef", initialMeshFile) + self.editor.setAttributeValue(newStudyFileName, "AttributeComment", initialMeshFile) + + if initialMeshObject!=None: + newLink=monStudyBuilder.NewObject(SOMesh) + monStudyBuilder.Addreference(newLink, initialMeshObject) + + newLink=monStudyBuilder.NewObject(SOMesh) + monStudyBuilder.Addreference(newLink, newStudyIter) + + if salome.sg.hasDesktop(): salome.sg.updateObjBrowser(0) + self.num+=1 + return True def PBSavePressed(self,NomHypo=False): - if NomHypo : text = '# Params for Hypothese : monHypo_Yams_'+str(self.num - 1)+"\n" - else : text = '# Save intermediate params \n' - text += "# Params for mesh : " + self.LE_MeshSmesh.text() +'\n' - for RB in self.GBOptim.findChildren(QRadioButton,): - if RB.isChecked()==True: - text+="Optimisation ='"+RB.text()+"'\n" - break - for RB in self.GBUnit.findChildren(QRadioButton,): - if RB.isChecked()==True: - text+="Units ='"+RB.text()+"'\n" - text+='Chordal_Tolerance_Deviation='+str(self.SP_Tolerance.value())+'\n' - - text+='Ridge_Detection=' + str(self.CB_Ridge.isChecked())+'\n' - text+='Split_Edge=' + str(self.CB_SplitEdge.isChecked())+'\n' - text+='Point_Smoothing=' + str(self.CB_Point.isChecked())+'\n' - text+='Geometrical_Approximation='+ str(self.SP_Geomapp.value()) +'\n' - text+='Ridge_Angle=' + str(self.SP_Ridge.value()) +'\n' - text+='Maximum_Size=' + str(self.SP_MaxSize.value()) +'\n' - text+='Minimum_Size=' + str(self.SP_MaxSize.value()) +'\n' - text+='Mesh_Gradation=' + str(self.SP_Gradation.value())+'\n' - - text+='Verbosity=' + str(self.SP_Verbosity.value())+'\n' - text+='Memory=' + str(self.SP_Memory.value())+'\n' - text+='\n\n' - - try : - f=open(self.paramsFile,'a') - except : - QMessageBox.warning( self, "File", "Unable to open "+self.paramsFile) - return - try : - f.write(text) - except : - QMessageBox.warning( self, "File", "Unable to write "+self.paramsFile) - return - f.close() + from datetime import datetime + if not(self.PrepareLigneCommande()): return + text = "# YAMS hypothesis parameters\n" + text += "# Params for mesh : " + self.LE_MeshSmesh.text() +"\n" + text += datetime.now().strftime("# Date : %d/%m/%y %H:%M:%S\n") + text += "# Command : "+self.commande+"\n" + text += self.getResumeData(separator="\n") + text += "\n\n" + + try: + f=open(self.paramsFile,"a") + except: + QMessageBox.warning(self, "File", "Unable to open "+self.paramsFile) + return + try: + f.write(text) + except: + QMessageBox.warning(self, "File", "Unable to write "+self.paramsFile) + return + f.close() + + def PBSaveHypPressed(self): + """save hypothesis in Object Browser""" + #QMessageBox.warning(self, "save Object Browser YAMS Hypothesis", "TODO") + + import smesh + import SMESH + import salome + from salome.kernel import studyedit + + maStudy=studyedit.getActiveStudy() + smesh.SetCurrentStudy(maStudy) + + self.editor = studyedit.getStudyEditor() + moduleEntry=self.editor.findOrCreateComponent("SMESH","SMESH") + HypReMeshEntry = self.editor.findOrCreateItem( + moduleEntry, name = "Plugins Hypotheses", icon="mesh_tree_hypo.png") #, comment = "HypoForRemeshing" ) + + monStudyBuilder=maStudy.NewBuilder() + monStudyBuilder.NewCommand() + newStudyIter=monStudyBuilder.NewObject(HypReMeshEntry) + self.editor.setAttributeValue(newStudyIter, "AttributeName", "YAMS Parameters_"+str(self.num)) + self.editor.setAttributeValue(newStudyIter, "AttributeComment", self.getResumeData(separator=" ; ")) + + if salome.sg.hasDesktop(): salome.sg.updateObjBrowser(0) + self.num+=1 + return True + + def SP_toStr(self, widget): + """only for a QLineEdit widget""" + #cr, pos=widget.validator().validate(res, 0) #n.b. "1,3" is acceptable !locale! + try: + val=float(widget.text()) + except: + QMessageBox.warning(self, widget.titleForWarning, "float value is incorrect: '"+widget.text()+"'") + res=str(widget.validator().bottom()) + widget.setProperty("text", res) + return res + valtest=widget.validator().bottom() + if valtest!=None: + if valvaltest: + QMessageBox.warning(self, widget.titleForWarning, "float value is over maximum: "+str(val)+" > "+str(valtest)) + res=str(valtest) + widget.setProperty("text", res) + return res + return str(val) + + def getResumeData(self, separator="\n"): + text="" + for RB in self.GBOptim.findChildren(QRadioButton,): + if RB.isChecked()==True: + text+="Optimisation="+RB.text()+separator + break + if self.RB_Absolute.isChecked(): + text+="Units=absolute"+separator + else: + text+="Units=relative"+separator + v=self.SP_toStr(self.SP_Tolerance) + text+="ChordalToleranceDeviation="+v+separator + text+="RidgeDetection="+str(self.CB_Ridge.isChecked())+separator + text+="SplitEdge="+str(self.CB_SplitEdge.isChecked())+separator + text+="PointSmoothing="+str(self.CB_Point.isChecked())+separator + text+="GeometricalApproximation="+str(self.SP_Geomapp.value())+separator + text+="RidgeAngle="+str(self.SP_Ridge.value())+separator + text+="MaximumSize="+str(self.SP_MaxSize.value())+separator + text+="MinimumSize="+str(self.SP_MinSize.value())+separator + text+="MeshGradation="+str(self.SP_Gradation.value())+separator + text+="Verbosity="+str(self.SP_Verbosity.value())+separator + text+="Memory="+str(self.SP_Memory.value())+separator + return str(text) + + def loadResumeData(self, hypothesis, separator="\n"): + text=str(hypothesis) + self.clean() + for slig in reversed(text.split(separator)): + lig=slig.strip() + #print "load ResumeData",lig + if lig=="": continue #skip blanck lines + if lig[0]=="#": break + try: + tit,value=lig.split("=") + if tit=="Optimisation": + for RB in self.GBUnit.findChildren(QRadioButton,): + RB.setChecked(False) + for RB in self.GBUnit.findChildren(QRadioButton,): + if RB.text()==value : + RB.setChecked(True) + break + if tit=="Units": + if value=="absolute": + self.RB_Absolute.setChecked(True) + self.RB_Relative.setChecked(False) + else: + self.RB_Absolute.setChecked(False) + self.RB_Relative.setChecked(True) + if tit=="ChordalToleranceDeviation": self.SP_Tolerance.setProperty("text", float(value)) + if tit=="RidgeDetection": self.CB_Ridge.setChecked(value=="True") + if tit=="SplitEdge": self.CB_SplitEdge.setChecked(value=="True") + if tit=="PointSmoothing": self.CB_Point.setChecked(value=="True") + if tit=="GeometricalApproximation": self.SP_Geomapp.setProperty("value", float(value)) + if tit=="RidgeAngle": self.SP_Ridge.setProperty("value", float(value)) + if tit=="MaximumSize": self.SP_MaxSize.setProperty("value", float(value)) + if tit=="MinimumSize": self.SP_MinSize.setProperty("value", float(value)) + if tit=="MeshGradation": self.SP_Gradation.setProperty("value", float(value)) + if tit=="Verbosity": self.SP_Verbosity.setProperty("value", int(float(value))) + if tit=="Memory": self.SP_Memory.setProperty("value", float(value)) + except: + QMessageBox.warning(self, "load YAMS Hypothesis", "Problem on '"+lig+"'") def PBLoadPressed(self): - try : - f=open(self.paramsFile,'r') - except : - QMessageBox.warning( self, "File", "Unable to open "+self.paramsFile) - return - try : - text=f.read() - except : - QMessageBox.warning( self, "File", "Unable to read "+self.paramsFile) - return - f.close() - d={} - exec text in d - for RB in self.GBOptim.findChildren(QRadioButton,): - if d['Optimisation']== RB.text(): - RB.setChecked(True) - break - for RB in self.GBUnit.findChildren(QRadioButton,): - if d['Units']== RB.text(): - RB.setChecked(True) - break - self.SP_Tolerance.setValue(d['Chordal_Tolerance_Deviation']) - - self.CB_Ridge.setChecked(d['Ridge_Detection']) - self.CB_Point.setChecked(d['Point_Smoothing']) - self.CB_SplitEdge.setChecked(d['Split_Edge']) - self.SP_Geomapp.setValue(d['Geometrical_Approximation']) - self.SP_Ridge.setValue(d['Ridge_Angle']) - self.SP_MaxSize.setValue(d['Maximum_Size']) - self.SP_MinSize.setValue(d['Minimum_Size']) - self.SP_Gradation.setValue(d['Mesh_Gradation']) - - self.SP_Verbosity.setValue(d['Verbosity']) - self.SP_Memory.setValue(d['Memory']) - - + """load last hypothesis saved in tail of file""" + try: + f=open(self.paramsFile,"r") + except: + QMessageBox.warning(self, "File", "Unable to open "+self.paramsFile) + return + try: + text=f.read() + except: + QMessageBox.warning(self, "File", "Unable to read "+self.paramsFile) + return + f.close() + self.loadResumeData(text, separator="\n") + + def PBLoadHypPressed(self): + """load hypothesis saved in Object Browser""" + #QMessageBox.warning(self, "load Object Browser YAMS hypothesis", "TODO") + import salome + from salome.kernel import studyedit + from salome.smesh.smeshstudytools import SMeshStudyTools + from salome.gui import helper as guihelper + from omniORB import CORBA + + mySObject, myEntry = guihelper.getSObjectSelected() + if CORBA.is_nil(mySObject) or mySObject==None: + QMessageBox.critical(self, "Hypothese", "select an Object Browser YAMS hypothesis") + return + + text=mySObject.GetComment() + + #a verification + if "Optimisation=" not in text: + QMessageBox.critical(self, "Load Hypothese", "Object Browser selection not a YAMS Hypothesis") + return + self.loadResumeData(text, separator=" ; ") + return + def PBCancelPressed(self): - self.close() + self.close() def PBMeshFilePressed(self): - fd = QFileDialog(self, "select an existing Mesh file", self.LE_MeshFile.text(), "Mesh-Files (*.mesh);;All Files (*)") - if fd.exec_(): - infile = fd.selectedFiles()[0] - self.LE_MeshFile.setText(infile) - self.fichierIn=infile.toLatin1() + fd = QFileDialog(self, "select an existing Mesh file", self.LE_MeshFile.text(), "Mesh-Files (*.mesh);;All Files (*)") + if fd.exec_(): + infile = fd.selectedFiles()[0] + self.LE_MeshFile.setText(infile) + self.fichierIn=infile.toLatin1() + self.MeshIn="" + self.LE_MeshSmesh.setText("") def setParamsFileName(self): - fd = QFileDialog(self, "select a file", self.LE_ParamsFile.text(), "dat Files (*.dat);;All Files (*)") - if fd.exec_(): - infile = fd.selectedFiles()[0] - self.LE_ParamsFile.setText(infile) - self.paramsFile=infile.toLatin1() - + fd = QFileDialog(self, "select a file", self.LE_ParamsFile.text(), "dat Files (*.dat);;All Files (*)") + if fd.exec_(): + infile = fd.selectedFiles()[0] + self.LE_ParamsFile.setText(infile) + self.paramsFile=infile.toLatin1() def meshFileNameChanged(self): - self.fichierIn=self.LE_MeshFile.text() - if os.path.exists(self.fichierIn): return - QMessageBox.warning( self, "Unknown File", "File doesn't exist") + self.fichierIn=str(self.LE_MeshFile.text()) + #print "meshFileNameChanged", self.fichierIn + if os.path.exists(self.fichierIn): + self.__selectedMesh=None + self.MeshIn="" + self.LE_MeshSmesh.setText("") + return + QMessageBox.warning(self, "Mesh file", "File doesn't exist") + + def meshSmeshNameChanged(self): + """only change by GUI mouse selection, otherwise clear""" + self.__selectedMesh = None + self.MeshIn="" + self.LE_MeshSmesh.setText("") + self.fichierIn="" + return def paramsFileNameChanged(self): - self.paramsFile=self.LE_ParamsFile.text() + self.paramsFile=self.LE_ParamsFile.text() def PBMeshSmeshPressed(self): - import salome - import smesh - from salome.kernel import studyedit - from salome.smesh.smeshstudytools import SMeshStudyTools - from salome.gui import helper as guihelper - from omniORB import CORBA - - mySObject, myEntry = guihelper.getSObjectSelected() - if CORBA.is_nil(mySObject) or mySObject==None: - QMessageBox.critical(self, "Mesh", "select an input mesh") - return - self.smeshStudyTool = SMeshStudyTools() + import salome + import smesh + from salome.kernel import studyedit + from salome.smesh.smeshstudytools import SMeshStudyTools + from salome.gui import helper as guihelper + from omniORB import CORBA + + mySObject, myEntry = guihelper.getSObjectSelected() + if CORBA.is_nil(mySObject) or mySObject==None: + QMessageBox.critical(self, "Mesh", "select an input mesh") + return + self.smeshStudyTool = SMeshStudyTools() + try: self.__selectedMesh = self.smeshStudyTool.getMeshObjectFromSObject(mySObject) - if CORBA.is_nil(self.__selectedMesh): - QMessageBox.critical(self, "Mesh", "select an input mesh") - return - myName = mySObject.GetName() - self.MeshIn=myName - self.LE_MeshSmesh.setText(myName) + except: + QMessageBox.critical(self, "Mesh", "select an input mesh") + return + if CORBA.is_nil(self.__selectedMesh): + QMessageBox.critical(self, "Mesh", "select an input mesh") + return + myName = mySObject.GetName() + #print "MeshSmeshNameChanged", myName + self.MeshIn=myName + self.LE_MeshSmesh.setText(myName) + self.LE_MeshFile.setText("") + self.fichierIn="" def prepareFichier(self): - self.fichierIn="/tmp/PourYam_"+str(self.num)+".mesh" - import SMESH - self.__selectedMesh.ExportGMF(self.__selectedMesh,self.fichierIn, True) + self.fichierIn="/tmp/ForYams_"+str(self.num)+".mesh" + import SMESH + self.__selectedMesh.ExportGMF(self.__selectedMesh, self.fichierIn, True) def PrepareLigneCommande(self): - self.commande="yams " - verbosity=str(self.SP_Verbosity.value()) - self.commande+="-v "+verbosity - for obj in self.mesRB.children(): - try : - if obj.isChecked(): - self.style=obj.objectName().remove(0,3) - self.style.replace("_","-") - break - except : - pass - self.commande+=" -O "+self.style.toLatin1() - if self.fichierIn=="" and self.MeshIn=="" : - QMessageBox.critical(self, "Mesh", "select an input mesh") - return False - if self.MeshIn!="" : self.prepareFichier() - if not (os.path.isfile(self.fichierIn)): - QMessageBox.critical(self, "File", "unable to read GMF Mesh in "+str(self.fichierIn)) - return False - - deb=os.path.splitext(self.fichierIn) - self.fichierOut=deb[0]+'.d.meshb' - - if self.RB_Absolute.isChecked()==True : - self.commande+=' -Dabsolute' - else : - self.commande+=' -Drelative' - self.commande+=',tolerance=%f'%self.SP_Tolerance.value() - if self.CB_Ridge.isChecked()==False : self.commande+=',-nr' - if self.CB_Point.isChecked()==False : self.commande+=',-ns' - if self.SP_Geomapp.value()!=0.04 : self.commande+=',geomapp=%f'%self.SP_Geomapp.value() - if self.SP_Ridge.value()!=45.0 : self.commande+=',ridge=%f'%self.SP_Ridge.value() - if self.SP_MaxSize.value()!=100 : self.commande+=',maxsize=%f'%self.SP_MaxSize.value() - if self.SP_MinSize.value()!=5 : self.commande+=',minsize=%f'%self.SP_MinSize.value() - if self.SP_Gradation.value()!=1.3 : self.commande+=',gradation=%f'%self.SP_MaxSize.value() - if self.CB_SplitEdge.isChecked()==True : self.commande+=',splitedge=1' - - if self.SP_Verbosity.value()!=3 : self.commande+=' -v %d'%self.SP_Verbosity.value() - if self.SP_Memory.value()!=0 : self.commande+=' -m %d'%self.SP_Memory.value() - - self.commande+=" "+self.fichierIn - return True + if self.fichierIn=="" and self.MeshIn=="": + QMessageBox.critical(self, "Mesh", "select an input mesh") + return False + if self.__selectedMesh!=None: self.prepareFichier() + if not (os.path.isfile(self.fichierIn)): + QMessageBox.critical(self, "File", "unable to read GMF Mesh in "+str(self.fichierIn)) + return False + + self.commande="yams" + verbosity=str(self.SP_Verbosity.value()) + self.commande+=" -v "+verbosity + for obj in self.GBOptim.findChildren(QRadioButton,): + try: + if obj.isChecked(): + self.style=obj.objectName().remove(0,3) + self.style.replace("_","-") + break + except: + pass + self.commande+=" -O "+self.style.toLatin1() + + deb=os.path.splitext(self.fichierIn) + self.fichierOut=deb[0] + ".d.meshb" + + if self.RB_Absolute.isChecked()==True : + self.commande+=" -Dabsolute" + else : + self.commande+=" -Drelative" + + v=self.SP_toStr(self.SP_Tolerance) + self.commande+=",tolerance="+v + if self.CB_Ridge.isChecked()==False : self.commande+=",-nr" + if self.CB_Point.isChecked()==False : self.commande+=",-ns" + if self.SP_Geomapp.value()!=0.04 : self.commande+=",geomapp=%f"%self.SP_Geomapp.value() + if self.SP_Ridge.value()!=45.0 : self.commande+=",ridge=%f"%self.SP_Ridge.value() + if self.SP_MaxSize.value()!=100 : self.commande+=",maxsize=%f"%self.SP_MaxSize.value() + if self.SP_MinSize.value()!=5 : self.commande+=",minsize=%f"%self.SP_MinSize.value() + if self.SP_Gradation.value()!=1.3 : self.commande+=",gradation=%f"%self.SP_MaxSize.value() + if self.CB_SplitEdge.isChecked()==True : self.commande+=",splitedge=1" + + if self.SP_Verbosity.value()!=3 : self.commande+=" -v %d"%self.SP_Verbosity.value() + if self.SP_Memory.value()!=0 : self.commande+=" -m %d"%self.SP_Memory.value() + + self.commande+=" "+self.fichierIn + return True def clean(self): - self.RB_0.setChecked(True) - self.RB_G.setChecked(False) - self.RB_U.setChecked(False) - self.RB_S.setChecked(False) - self.RB_2.setChecked(False) - self.RB_1.setChecked(False) - self.RB_Absolute.setChecked(False) - self.RB_Relative.setChecked(True) - self.SP_Tolerance.setProperty("value", 0.1) - self.SP_Geomapp.setProperty("value", 0.04) - self.SP_Ridge.setProperty("value", 45.0) - self.SP_Gradation.setProperty("value", 1.3) - self.CB_Ridge.setChecked(True) - self.CB_Point.setChecked(True) - self.CB_SplitEdge.setChecked(False) - self.SP_MaxSize.setProperty("value", -2.0) - self.SP_MinSize.setProperty("value", -2.0) - self.SP_Verbosity.setProperty("value", 3) - self.SP_Memory.setProperty("value", 0) - + self.RB_0.setChecked(True) + self.RB_G.setChecked(False) + self.RB_U.setChecked(False) + self.RB_S.setChecked(False) + self.RB_2.setChecked(False) + self.RB_1.setChecked(False) + self.RB_Absolute.setChecked(False) + self.RB_Relative.setChecked(True) + self.SP_Tolerance.setProperty("text", "10.") + self.SP_Geomapp.setProperty("value", 0.04) + self.SP_Ridge.setProperty("value", 45.0) + self.SP_Gradation.setProperty("value", 1.3) + self.CB_Ridge.setChecked(True) + self.CB_Point.setChecked(True) + self.CB_SplitEdge.setChecked(False) + self.SP_MaxSize.setProperty("value", -2.0) + self.SP_MinSize.setProperty("value", -2.0) + self.SP_Verbosity.setProperty("value", 3) + self.SP_Memory.setProperty("value", 0) __dialog=None def getDialog(): @@ -314,3 +503,23 @@ def getDialog(): # __dialog.clean() return __dialog +# +# ============================================================================== +# Basic use cases and unit test functions +# ============================================================================== +# +def TEST_MonYamsPlugDialog(): + #print "TEST_YamsMonPlugDialog" + import sys + from PyQt4.QtGui import QApplication + from PyQt4.QtCore import QObject, SIGNAL, SLOT + app = QApplication(sys.argv) + QObject.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()")) + + dlg=MonYamsPlugDialog() + dlg.show() + sys.exit(app.exec_()) + +if __name__ == "__main__": + TEST_MonYamsPlugDialog() + pass diff --git a/src/Tools/YamsPlug/yamsplug_plugin.py b/src/Tools/YamsPlug/yamsplug_plugin.py index cc7a7c130..f61ed050f 100644 --- a/src/Tools/YamsPlug/yamsplug_plugin.py +++ b/src/Tools/YamsPlug/yamsplug_plugin.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- # Copyright (C) 2006-2013 EDF R&D # # This library is free software; you can redistribute it and/or @@ -34,11 +35,12 @@ def YamsLct(context): from PyQt4.QtGui import QFileDialog from PyQt4.QtGui import QMessageBox + #prior test to avoid unnecessary user GUI work with ending crash try : os.environ['DISTENE_LICENCE_FILE_FOR_YAMS'] except: - QMessageBox.warning(None,"Products","Distene's products are not installed") + QMessageBox.warning(None,"Products","Distene's product Yams is not installed.\nrequired environment variable:\nDISTENE_LICENCE_FILE_FOR_YAMS='/.../dlim8.var.sh'") return import monYamsPlugDialog - window=monYamsPlugDialog.getDialog() + window=monYamsPlugDialog.getDialog() window.show()