Salome HOME
22355: EDF SMESH: New 1D hypothesis "Adaptive"
authoreap <eap@opencascade.com>
Mon, 11 Nov 2013 11:07:44 +0000 (11:07 +0000)
committereap <eap@opencascade.com>
Mon, 11 Nov 2013 11:07:44 +0000 (11:07 +0000)
25 files changed:
doc/salome/examples/CMakeLists.txt
doc/salome/examples/defining_hypotheses_adaptive1d.py [new file with mode: 0644]
doc/salome/gui/SMESH/images/adaptive1d.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/adaptive1d_sample_mesh.png [new file with mode: 0644]
doc/salome/gui/SMESH/input/1d_meshing_hypo.doc
doc/salome/gui/SMESH/input/about_hypo.doc
doc/salome/gui/SMESH/input/tui_defining_hypotheses.doc
idl/SMESH_BasicHypothesis.idl
resources/StdMeshers.xml.in
src/SMESH/SMESH_Mesh.cxx
src/SMESHGUI/SMESHGUI_Hypotheses.cxx
src/SMESH_I/SMESH_Gen_i.hxx
src/SMESH_SWIG/StdMeshersBuilder.py
src/StdMeshers/CMakeLists.txt
src/StdMeshers/StdMeshers_Adaptive1D.cxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_Adaptive1D.hxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_Regular_1D.cxx
src/StdMeshers/StdMeshers_Regular_1D.hxx
src/StdMeshersGUI/StdMeshersGUI_StdHypothesisCreator.cxx
src/StdMeshersGUI/StdMeshers_images.ts
src/StdMeshersGUI/StdMeshers_msg_en.ts
src/StdMeshers_I/CMakeLists.txt
src/StdMeshers_I/StdMeshers_Adaptive1D_i.cxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_Adaptive1D_i.hxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_i.cxx

index d8c4631f8e58fb85f675023a5d93b5fbfd8b5f4c..aefec539df4b85ab936168459817e9efb148314d 100644 (file)
@@ -63,6 +63,7 @@ SET(GOOD_TESTS
   defining_hypotheses_ex14.py 
   defining_hypotheses_ex15.py 
   defining_hypotheses_ex16.py 
   defining_hypotheses_ex14.py 
   defining_hypotheses_ex15.py 
   defining_hypotheses_ex16.py 
+  defining_hypotheses_adaptive1d.py
   filters_ex01.py 
   filters_ex03.py 
   filters_ex04.py 
   filters_ex01.py 
   filters_ex03.py 
   filters_ex04.py 
diff --git a/doc/salome/examples/defining_hypotheses_adaptive1d.py b/doc/salome/examples/defining_hypotheses_adaptive1d.py
new file mode 100644 (file)
index 0000000..f53434a
--- /dev/null
@@ -0,0 +1,30 @@
+import salome, math
+salome.salome_init()
+from salome.geom import geomBuilder
+geompy = geomBuilder.New(salome.myStudy)
+from salome.smesh import smeshBuilder
+smesh =  smeshBuilder.New(salome.myStudy)
+
+
+box   = geompy.MakeBoxDXDYDZ( 100, 100, 100 )
+tool  = geompy.MakeTranslation( box, 50, 0, 10 )
+axis  = geompy.MakeVector( geompy.MakeVertex( 100, 0, 100 ),geompy.MakeVertex( 100, 10, 100 ),)
+tool  = geompy.Rotate( tool, axis, math.pi * 25 / 180. )
+shape = geompy.MakeCut( box, tool )
+cyl   = geompy.MakeCylinder( geompy.MakeVertex( -10,5, 95 ), geompy.MakeVectorDXDYDZ(1,0,0), 2, 90)
+shape = geompy.MakeCut( shape, cyl )
+tool  = geompy.MakeBoxTwoPnt( geompy.MakeVertex( -10, 2, 15 ), geompy.MakeVertex( 90, 5, 16 ))
+shape = geompy.MakeCut( shape, tool, theName="shape" )
+
+# Parameters of Adaptive hypothesis. minSize and maxSize are such that they do not limit
+# size of segments because size of geometrical features lies within [2.-100.] range, hence
+# size of segments is defined by deflection parameter and size of geometrical features only.
+minSize = 0.1
+maxSize = 200
+deflection = 0.05
+
+mesh = smesh.Mesh( shape )
+mesh.Segment().Adaptive( minSize, maxSize, deflection )
+mesh.Triangle( smeshBuilder.NETGEN_2D )
+mesh.Compute()
+
diff --git a/doc/salome/gui/SMESH/images/adaptive1d.png b/doc/salome/gui/SMESH/images/adaptive1d.png
new file mode 100644 (file)
index 0000000..8091c8d
Binary files /dev/null and b/doc/salome/gui/SMESH/images/adaptive1d.png differ
diff --git a/doc/salome/gui/SMESH/images/adaptive1d_sample_mesh.png b/doc/salome/gui/SMESH/images/adaptive1d_sample_mesh.png
new file mode 100644 (file)
index 0000000..034207f
Binary files /dev/null and b/doc/salome/gui/SMESH/images/adaptive1d_sample_mesh.png differ
index 367a0d0b5abe489daf5be5ae49ab5bcd9c5da4cc..5deb1344a9ec13da3beb6b16ce2cf28b0b9a1457 100644 (file)
@@ -4,6 +4,7 @@
 
 <br>
 <ul>
 
 <br>
 <ul>
+<li>\ref adaptive_1d_anchor "Adaptive"</li>
 <li>\ref arithmetic_1d_anchor "Arithmetic 1D"</li>
 <li>\ref average_length_anchor "Local Length"</li>
 <li>\ref max_length_anchor "Max Size"</li>
 <li>\ref arithmetic_1d_anchor "Arithmetic 1D"</li>
 <li>\ref average_length_anchor "Local Length"</li>
 <li>\ref max_length_anchor "Max Size"</li>
 <li>\ref fixed_points_1d_anchor "Fixed points 1D"</li>
 </ul>
 
 <li>\ref fixed_points_1d_anchor "Fixed points 1D"</li>
 </ul>
 
+<br>
+\anchor adaptive_1d_anchor
+<h2>Adaptive hypothesis</h2>
+
+<b>Adaptive</b> hypothesis allows to split edges into segments with a
+length that depends on curvature of edges and faces and is limited
+from up and down. In addition length of a segment depends on lengths
+of adjacent segments (that can't differ more than twice) and on
+distance to close geometrical entities (edges and faces) to avoid
+creation of narrow 2D elements.
+
+\image html adaptive1d.png
+
+<b>Min size</b> parameter limits minimal segment size. <b>Max size</b>
+parameter defines length of segments on stright edges. \b Deflection
+parameter gives maximal distance of a segment from a curved edge.
+
+\image html adaptive1d_sample_mesh.png "A geometry and a mesh generated on this geometry using Adaptive hypothesis and Netgen 2D algorithm - the size of mesh segments reflects size of geometrical features"
+
+<b>See Also</b> a \ref tui_1d_adaptive "sample TUI Script" that
+creates the mesh of the above image.
+
 <br>
 \anchor arithmetic_1d_anchor
 <h2>Arithmetic 1D hypothesis</h2>
 <br>
 \anchor arithmetic_1d_anchor
 <h2>Arithmetic 1D hypothesis</h2>
@@ -26,7 +49,7 @@ The direction of the splitting is defined by the orientation of the underlying g
 <b>"Reverse Edges"</b> list box allows to specify the edges for which the splitting should be made 
 in the direction opposing to their orientation. This list box is enabled only if the geometry object 
 is selected for the meshing. In this case the user can select edges to be reversed either directly 
 <b>"Reverse Edges"</b> list box allows to specify the edges for which the splitting should be made 
 in the direction opposing to their orientation. This list box is enabled only if the geometry object 
 is selected for the meshing. In this case the user can select edges to be reversed either directly 
-picking them in the 3D viewer or by selecting the edges or groups of edges in the Object browser.
+picking them in the 3D viewer or by selecting the edges or groups of edges in the Object Browser.
 
 \image html a-arithmetic1d.png
 
 
 \image html a-arithmetic1d.png
 
@@ -117,7 +140,7 @@ The direction of the splitting is defined by the orientation of the underlying g
 <b>"Reverse Edges"</b> list box allows to specify the edges for which the splitting should be made 
 in the direction opposing to their orientation. This list box is enabled only if the geometry object 
 is selected for the meshing. In this case the user can select edges to be reversed either directly 
 <b>"Reverse Edges"</b> list box allows to specify the edges for which the splitting should be made 
 in the direction opposing to their orientation. This list box is enabled only if the geometry object 
 is selected for the meshing. In this case the user can select edges to be reversed either directly 
-picking them in the 3D viewer or by selecting the edges or groups of edges in the Object browser.
+picking them in the 3D viewer or by selecting the edges or groups of edges in the Object Browser.
 
 \image html image46.gif
 
 
 \image html image46.gif
 
@@ -166,7 +189,7 @@ The direction of the splitting is defined by the orientation of the underlying g
 <b>"Reverse Edges"</b> list box allows to specify the edges for which the splitting should be made 
 in the direction opposing to their orientation. This list box is enabled only if the geometry object 
 is selected for the meshing. In this case the user can select edges to be reversed either directly 
 <b>"Reverse Edges"</b> list box allows to specify the edges for which the splitting should be made 
 in the direction opposing to their orientation. This list box is enabled only if the geometry object 
 is selected for the meshing. In this case the user can select edges to be reversed either directly 
-picking them in the 3D viewer or by selecting the edges or groups of edges in the Object browser.
+picking them in the 3D viewer or by selecting the edges or groups of edges in the Object Browser.
 
 \image html a-startendlength.png
 
 
 \image html a-startendlength.png
 
@@ -215,7 +238,7 @@ direction opposite to their orientation. This list box is enabled only
 if the geometrical object is selected for meshing. In this case it is
 possible to select the edges to be reversed either directly picking them in
 the 3D viewer or selecting the edges or groups of edges in the
 if the geometrical object is selected for meshing. In this case it is
 possible to select the edges to be reversed either directly picking them in
 the 3D viewer or selecting the edges or groups of edges in the
-Object browser.
+Object Browser.
 
 \image html mesh_fixedpnt.png "Example of a submesh on the edge built using Fixed points 1D hypothesis"
 
 
 \image html mesh_fixedpnt.png "Example of a submesh on the edge built using Fixed points 1D hypothesis"
 
index e4bf36ca0945293fa2f49ca48b957e79c4618a66..09768cc7cb2a6fc6c8ae86258edb61a869f02d6e 100644 (file)
@@ -3,8 +3,8 @@
 \page about_hypo_page About Hypotheses
 
 \b Hypotheses represent boundary conditions which will be taken into
 \page about_hypo_page About Hypotheses
 
 \b Hypotheses represent boundary conditions which will be taken into
-account at calculations of meshes or sub-meshes basing on geometrical
-objects. These hypotheses allow you to manage the level of detail of
+account at calculations of meshes or sub-meshes
+These hypotheses allow you to manage the level of detail of
 the resulting meshes or sub-meshes: when applying different hypotheses
 with different parameters you can preset the quantity or size of
 elements which will compose your mesh. So, it will be possible to
 the resulting meshes or sub-meshes: when applying different hypotheses
 with different parameters you can preset the quantity or size of
 elements which will compose your mesh. So, it will be possible to
@@ -15,12 +15,13 @@ In \b MESH there are the following Basic Hypotheses:
 <li>\subpage a1d_meshing_hypo_page "1D Hypotheses" (for meshing of 
 <b>edges</b>):</li>
 <ul>
 <li>\subpage a1d_meshing_hypo_page "1D Hypotheses" (for meshing of 
 <b>edges</b>):</li>
 <ul>
-<li>\ref arithmetic_1d_anchor "Arithmetic 1D"</li>
+<li>\ref number_of_segments_anchor "Number of segments"</li>
 <li>\ref average_length_anchor "Local Length"</li>
 <li>\ref max_length_anchor "Max Size"</li>
 <li>\ref average_length_anchor "Local Length"</li>
 <li>\ref max_length_anchor "Max Size"</li>
-<li>\ref deflection_1d_anchor "Deflection 1D"</li>
-<li>\ref number_of_segments_anchor "Number of segments"</li>
+<li>\ref adaptive_1d_anchor "Adaptive"</li>
+<li>\ref arithmetic_1d_anchor "Arithmetic 1D"</li>
 <li>\ref start_and_end_length_anchor "Start and end length"</li>
 <li>\ref start_and_end_length_anchor "Start and end length"</li>
+<li>\ref deflection_1d_anchor "Deflection 1D"</li>
 <li>\ref automatic_length_anchor "Automatic Length"</li>
 </ul>
 <li>\subpage a2d_meshing_hypo_page "2D Hypotheses" (for meshing of <b>faces</b>):</li>
 <li>\ref automatic_length_anchor "Automatic Length"</li>
 </ul>
 <li>\subpage a2d_meshing_hypo_page "2D Hypotheses" (for meshing of <b>faces</b>):</li>
index 71abf33b6e68bb8018930208f3c451ce270ef20b..333017d774aa8ca4d5a5bb9e834869528805f98e 100644 (file)
@@ -7,6 +7,7 @@ This page provides example codes of \ref tui_defining_meshing_algos
 <ul>
 <li>Wire discretisation 1D algorithm
   <ul>
 <ul>
 <li>Wire discretisation 1D algorithm
   <ul>
+    <li>\ref tui_1d_adaptive "Adaptive 1D" hypothesis</li>
     <li>\ref tui_1d_arithmetic "Arithmetic 1D" hypothesis</li>
     <li>\ref tui_deflection_1d "Deflection 1D and Number of Segments" hypotheses</li>
     <li>\ref tui_start_and_end_length "Start and End Length" hypotheses</li>
     <li>\ref tui_1d_arithmetic "Arithmetic 1D" hypothesis</li>
     <li>\ref tui_deflection_1d "Deflection 1D and Number of Segments" hypotheses</li>
     <li>\ref tui_start_and_end_length "Start and End Length" hypotheses</li>
@@ -46,6 +47,11 @@ This page provides example codes of \ref tui_defining_meshing_algos
 <h3>Arithmetic 1D</h3>
 \tui_script{defining_hypotheses_ex01.py}
 
 <h3>Arithmetic 1D</h3>
 \tui_script{defining_hypotheses_ex01.py}
 
+<br>
+\anchor tui_1d_adaptive
+<h3>Adaptive</h3>
+\tui_script{defining_hypotheses_adaptive1d.py}
+
 <br>
 \anchor tui_deflection_1d
 <h3>Deflection 1D and Number of Segments</h3>
 <br>
 \anchor tui_deflection_1d
 <h3>Deflection 1D and Number of Segments</h3>
index b2bca113cd43759713429f1a2a48f96ad12776c2..798475b30318eb0a013fc77ebdabaccfd1c90f38 100644 (file)
@@ -385,7 +385,6 @@ module StdMeshers
     double GetDeflection();
   };
 
     double GetDeflection();
   };
 
-
   /*!
    * StdMeshers_FixedPoints1D: interface of "Fixed points 1D" hypothesis
    */
   /*!
    * StdMeshers_FixedPoints1D: interface of "Fixed points 1D" hypothesis
    */
@@ -433,6 +432,30 @@ module StdMeshers
     string GetObjectEntry();
   };
 
     string GetObjectEntry();
   };
 
+  /*!
+   * StdMeshers_Adaptive1D: interface of "Adaptive" hypothesis
+   */
+  interface StdMeshers_Adaptive1D : SMESH::SMESH_Hypothesis
+  {
+    /*!
+     * Sets minimal allowed segment length
+     */
+    void SetMinSize(in double minSegLen) raises (SALOME::SALOME_Exception);
+    double GetMinSize();
+
+    /*!
+     * Sets maximal allowed segment length
+     */
+    void SetMaxSize(in double maxSegLen) raises (SALOME::SALOME_Exception);
+    double GetMaxSize();
+
+    /*!
+     * Sets <deflection> parameter value, 
+     * i.e. a maximal allowed distance between a segment and an edge.
+     */
+    void SetDeflection(in double deflection) raises (SALOME::SALOME_Exception);
+    double GetDeflection();
+  };
 
   /*!
    * StdMeshers_MaxElementVolume: interface of "Max. Hexahedron or Tetrahedron Volume" hypothesis
 
   /*!
    * StdMeshers_MaxElementVolume: interface of "Max. Hexahedron or Tetrahedron Volume" hypothesis
index c205f0355397bc542ea5a567849becbc7dcaf1e9..d80b4e7d997f9004e31774b651f44cd1cbff54a9 100644 (file)
                 icon-id  ="mesh_hypo_length.png"
                 dim      ="1"/>
 
                 icon-id  ="mesh_hypo_length.png"
                 dim      ="1"/>
 
+    <hypothesis type     ="Adaptive1D"
+                label-id ="Adaptive"
+                icon-id  ="mesh_hypo_length.png"
+                dim      ="1"/>
+
     <hypothesis type     ="Propagation"
                 label-id ="Propagation of 1D Hyp. on Opposite Edges"
                 icon-id  ="mesh_hypo_length.png"
     <hypothesis type     ="Propagation"
                 label-id ="Propagation of 1D Hyp. on Opposite Edges"
                 icon-id  ="mesh_hypo_length.png"
     <algorithm type     ="Regular_1D"
               label-id ="Wire Discretisation"
               icon-id  ="mesh_algo_regular.png"
     <algorithm type     ="Regular_1D"
               label-id ="Wire Discretisation"
               icon-id  ="mesh_algo_regular.png"
-               hypos    ="LocalLength,MaxLength,Arithmetic1D,StartEndLength,NumberOfSegments,Deflection1D,AutomaticLength,FixedPoints1D"
+               hypos    ="Adaptive1D,LocalLength,MaxLength,Arithmetic1D,StartEndLength,NumberOfSegments,Deflection1D,AutomaticLength,FixedPoints1D"
                opt-hypos="Propagation,QuadraticMesh"
                input    ="VERTEX"
                output   ="EDGE"
                opt-hypos="Propagation,QuadraticMesh"
                input    ="VERTEX"
                output   ="EDGE"
         <hypo>Arithmetic1D=Arithmetic1D(SetStartLength(),SetEndLength(),SetReversedEdges())</hypo>
         <hypo>StartEndLength=StartEndLength(SetStartLength(),SetEndLength(),SetReversedEdges())</hypo>
         <hypo>Deflection1D=Deflection1D(SetDeflection())</hypo>
         <hypo>Arithmetic1D=Arithmetic1D(SetStartLength(),SetEndLength(),SetReversedEdges())</hypo>
         <hypo>StartEndLength=StartEndLength(SetStartLength(),SetEndLength(),SetReversedEdges())</hypo>
         <hypo>Deflection1D=Deflection1D(SetDeflection())</hypo>
+        <hypo>Adaptive1D=Adaptive(SetMinSize(),SetMaxSize(),SetDeflection())</hypo>
         <hypo>AutomaticLength=AutomaticLength(SetFineness())</hypo>
         <hypo>FixedPoints1D=FixedPoints1D(SetPoints(),SetNbSegments(),SetReversedEdges())</hypo>
         <hypo>Propagation=Propagation()</hypo>
         <hypo>AutomaticLength=AutomaticLength(SetFineness())</hypo>
         <hypo>FixedPoints1D=FixedPoints1D(SetPoints(),SetNbSegments(),SetReversedEdges())</hypo>
         <hypo>Propagation=Propagation()</hypo>
     <algorithm type     ="CompositeSegment_1D"
               label-id ="Composite Side Discretisation"
               icon-id  ="mesh_algo_regular.png"
     <algorithm type     ="CompositeSegment_1D"
               label-id ="Composite Side Discretisation"
               icon-id  ="mesh_algo_regular.png"
-               hypos    ="LocalLength,MaxLength,Arithmetic1D,StartEndLength,NumberOfSegments,Deflection1D,AutomaticLength,FixedPoints1D"
+               hypos    ="Adaptive1D,LocalLength,MaxLength,Arithmetic1D,StartEndLength,NumberOfSegments,Deflection1D,AutomaticLength,FixedPoints1D"
                opt-hypos="Propagation,QuadraticMesh"
                input    ="VERTEX"
                output   ="EDGE"
                opt-hypos="Propagation,QuadraticMesh"
                input    ="VERTEX"
                output   ="EDGE"
         <hypo>Arithmetic1D=Arithmetic1D(SetStartLength(),SetEndLength(),SetReversedEdges())</hypo>
         <hypo>StartEndLength=StartEndLength(SetStartLength(),SetEndLength(),SetReversedEdges())</hypo>
         <hypo>Deflection1D=Deflection1D(SetDeflection())</hypo>
         <hypo>Arithmetic1D=Arithmetic1D(SetStartLength(),SetEndLength(),SetReversedEdges())</hypo>
         <hypo>StartEndLength=StartEndLength(SetStartLength(),SetEndLength(),SetReversedEdges())</hypo>
         <hypo>Deflection1D=Deflection1D(SetDeflection())</hypo>
+        <hypo>Adaptive1D=Adaptive(SetMinSize(),SetMaxSize(),SetDeflection())</hypo>
         <hypo>AutomaticLength=AutomaticLength(SetFineness())</hypo>
         <hypo>FixedPoints1D=FixedPoints1D(SetPoints(),SetNbSegments(),SetReversedEdges())</hypo>
         <hypo>Propagation=Propagation()</hypo>
         <hypo>AutomaticLength=AutomaticLength(SetFineness())</hypo>
         <hypo>FixedPoints1D=FixedPoints1D(SetPoints(),SetNbSegments(),SetReversedEdges())</hypo>
         <hypo>Propagation=Propagation()</hypo>
index 6f1edc645e019e56b35d079c44307312da9b803d..4c1383356d4adc41e1f8e0f56bd34e251d8fa287 100644 (file)
@@ -876,7 +876,7 @@ SMESH_Hypothesis * SMESH_Mesh::GetHypothesis(const int anHypId) const
 {
   StudyContextStruct *sc = _gen->GetStudyContext(_studyId);
   if (sc->mapHypothesis.find(anHypId) == sc->mapHypothesis.end())
 {
   StudyContextStruct *sc = _gen->GetStudyContext(_studyId);
   if (sc->mapHypothesis.find(anHypId) == sc->mapHypothesis.end())
-    return false;
+    return NULL;
 
   SMESH_Hypothesis *anHyp = sc->mapHypothesis[anHypId];
   return anHyp;
 
   SMESH_Hypothesis *anHyp = sc->mapHypothesis[anHypId];
   return anHyp;
index 77d8ec1b22e5ce2fe69a559b03a9b611596d987f..fa9add8e0b6a73cffd1ccfe5c1feb9e8bccb49ec 100644 (file)
@@ -561,6 +561,8 @@ QString SMESHGUI_GenericHypothesisCreator::helpPage() const
     aHelpFileName = "a1d_meshing_hypo_page.html#start_and_end_length_anchor";
   else if ( aHypType == "Deflection1D")
     aHelpFileName = "a1d_meshing_hypo_page.html#deflection_1d_anchor";
     aHelpFileName = "a1d_meshing_hypo_page.html#start_and_end_length_anchor";
   else if ( aHypType == "Deflection1D")
     aHelpFileName = "a1d_meshing_hypo_page.html#deflection_1d_anchor";
+  else if ( aHypType == "Adaptive1D")
+    aHelpFileName = "a1d_meshing_hypo_page.html#adaptive_1d_anchor";
   else if ( aHypType == "AutomaticLength")
     aHelpFileName = "a1d_meshing_hypo_page.html#automatic_length_anchor";
   else if ( aHypType == "NumberOfSegments")
   else if ( aHypType == "AutomaticLength")
     aHelpFileName = "a1d_meshing_hypo_page.html#automatic_length_anchor";
   else if ( aHypType == "NumberOfSegments")
index 4e2b9b754a6a4015b25abd0a123e0bcd98b8b8e1..6b134e51f065449ad93babf5f350f308f858e335 100644 (file)
@@ -486,8 +486,8 @@ public:
 
   // SIMAN-related functions (check out/check in) : import data to study
   virtual Engines::ListOfIdentifiers* importData(CORBA::Long studyId,
 
   // SIMAN-related functions (check out/check in) : import data to study
   virtual Engines::ListOfIdentifiers* importData(CORBA::Long studyId,
-                                                Engines::DataContainer_ptr data,
-                                                const Engines::ListOfOptions& options);
+                                                 Engines::DataContainer_ptr data,
+                                                 const Engines::ListOfOptions& options);
   // SIMAN-related functions (check out/check in) : get modified data
   virtual Engines::ListOfData* getModifiedData(CORBA::Long studyId);
 
   // SIMAN-related functions (check out/check in) : get modified data
   virtual Engines::ListOfData* getModifiedData(CORBA::Long studyId);
 
index ee05f82efc585e1e6702342549174a57de2e734d..32d2724f9cfea963173eb6a35fe56054d9a5880a 100644 (file)
@@ -178,6 +178,28 @@ class StdMeshersBuilder_Segment(Mesh_Algorithm):
                                 return True
         return False
 
                                 return True
         return False
 
+    ## Defines "Adaptive" hypothesis to cut an edge into segments keeping segment size
+    #  within the given range and considering (1) deflection of segments from the edge
+    #  and (2) distance from segments to closest edges and faces to have segment length
+    #  not longer than two times shortest distances to edges and faces.
+    #  @param minSize defines the minimal allowed segment length
+    #  @param maxSize defines the maximal allowed segment length
+    #  @param deflection defines the maximal allowed distance from a segment to an edge
+    #  @param UseExisting if ==true - searches for an existing hypothesis created with
+    #                     the same parameters, else (default) - creates a new one
+    #  @return an instance of StdMeshers_Adaptive1D hypothesis
+    #  @ingroup l3_hypos_1dhyps
+    def Adaptive(self, minSize, maxSize, deflection, UseExisting=False):
+        compFun = lambda hyp, args: ( IsEqual(hyp.GetMinSize(), args[0]) and \
+                                      IsEqual(hyp.GetMaxSize(), args[1]) and \
+                                      IsEqual(hyp.GetDeflection(), args[2]))
+        hyp = self.Hypothesis("Adaptive1D", [minSize, maxSize, deflection],
+                              UseExisting=UseExisting, CompareMethod=compFun)
+        hyp.SetMinSize(minSize)
+        hyp.SetMaxSize(maxSize)
+        hyp.SetDeflection(deflection)
+        return hyp
+
     ## Defines "Arithmetic1D" hypothesis to cut an edge in several segments with increasing arithmetic length
     #  @param start defines the length of the first segment
     #  @param end   defines the length of the last  segment
     ## Defines "Arithmetic1D" hypothesis to cut an edge in several segments with increasing arithmetic length
     #  @param start defines the length of the first segment
     #  @param end   defines the length of the last  segment
index 040bb90f0dd9371e37f89ff5ba2836e0519cc5af..de84b50262e8a2ad60486d545355d343ac43a2d1 100644 (file)
@@ -186,6 +186,7 @@ SET(StdMeshers_SOURCES
   StdMeshers_Projection_1D2D.cxx
   StdMeshers_CartesianParameters3D.cxx
   StdMeshers_Cartesian_3D.cxx
   StdMeshers_Projection_1D2D.cxx
   StdMeshers_CartesianParameters3D.cxx
   StdMeshers_Cartesian_3D.cxx
+  StdMeshers_Adaptive1D.cxx
 )
 
 IF(SALOME_SMESH_ENABLE_MEFISTO)
 )
 
 IF(SALOME_SMESH_ENABLE_MEFISTO)
diff --git a/src/StdMeshers/StdMeshers_Adaptive1D.cxx b/src/StdMeshers/StdMeshers_Adaptive1D.cxx
new file mode 100644 (file)
index 0000000..5078dd4
--- /dev/null
@@ -0,0 +1,1194 @@
+// Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//  File   : StdMeshers_Adaptive1D.cxx
+//  Module : SMESH
+//
+#include "StdMeshers_Adaptive1D.hxx"
+
+#include "SMESH_Gen.hxx"
+#include "SMESH_Mesh.hxx"
+#include "SMESH_MesherHelper.hxx"
+#include "SMESH_Octree.hxx"
+#include "SMESH_subMesh.hxx"
+#include "SMESH_HypoFilter.hxx"
+
+#include <Utils_SALOME_Exception.hxx>
+
+#include <BRepAdaptor_Curve.hxx>
+#include <BRepAdaptor_Surface.hxx>
+#include <BRepMesh_IncrementalMesh.hxx>
+#include <BRep_Tool.hxx>
+#include <Bnd_B3d.hxx>
+#include <GCPnts_AbscissaPoint.hxx>
+#include <GeomAdaptor_Curve.hxx>
+#include <Geom_Curve.hxx>
+#include <Poly_Array1OfTriangle.hxx>
+#include <Poly_Triangulation.hxx>
+#include <TColgp_Array1OfPnt.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopLoc_Location.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <gp_Lin.hxx>
+#include <gp_Pnt.hxx>
+
+#include <limits>
+#include <vector>
+#include <set>
+
+using namespace std;
+
+namespace // internal utils
+{
+  //================================================================================
+  /*!
+   * \brief Working data of an EDGE
+   */
+  struct EdgeData
+  {
+    struct ProbePnt
+    {
+      gp_Pnt myP;
+      double myU;
+      double mySegSize;
+      ProbePnt( gp_Pnt p, double u, double sz=1e100 ): myP( p ), myU( u ), mySegSize( sz ) {}
+    };
+    BRepAdaptor_Curve myC3d;
+    double            myLength;
+    list< ProbePnt >  myPoints;
+
+    typedef list< ProbePnt >::iterator TPntIter;
+    void AddPoint( TPntIter where, double u )
+    {
+      myPoints.insert( where, ProbePnt( myC3d.Value( u ), u ));
+    }
+    const ProbePnt& First() const { return myPoints.front(); }
+    const ProbePnt& Last()  const { return myPoints.back(); }
+    const TopoDS_Edge& Edge() const { return myC3d.Edge(); }
+  };
+
+  //================================================================================
+  /*!
+   * \brief Bnd_B3d with access to its center and half-size
+   */
+  struct BBox : public Bnd_B3d
+  {
+    gp_XYZ Center() const { return gp_XYZ( myCenter[0], myCenter[1], myCenter[2] ); }
+    gp_XYZ HSize()  const { return gp_XYZ( myHSize[0],  myHSize[1],  myHSize[2]  ); }
+    double Size()   const { return 2 * myHSize[0]; }
+  };
+  //================================================================================
+  /*!
+   * \brief Octree of local segment size
+   */
+  class SegSizeTree : public SMESH_Octree
+  {
+    double mySegSize; // segment size
+
+    // structure holding some common parameters of SegSizeTree
+    struct _CommonData : public SMESH_TreeLimit
+    {
+      double myGrading, myMinSize, myMaxSize;
+    };
+    _CommonData* getData() const { return (_CommonData*) myLimit; }
+
+    SegSizeTree(double size): SMESH_Octree(), mySegSize(size)
+    {
+      allocateChildren();
+    }
+    void allocateChildren()
+    {
+      myChildren = new SMESH_Octree::TBaseTree*[nbChildren()];
+      for ( int i = 0; i < nbChildren(); ++i )
+        myChildren[i] = NULL;
+    }
+    virtual box_type* buildRootBox() { return 0; }
+    virtual SegSizeTree* newChild() const { return 0; }
+    virtual void buildChildrenData() {}
+
+  public:
+
+    SegSizeTree( Bnd_B3d & bb, double grading, double mixSize, double maxSize);
+    void   SetSize( const gp_Pnt& p, double size );
+    double SetSize( const gp_Pnt& p1, const gp_Pnt& p2 );
+    double GetSize( const gp_Pnt& p ) const;
+    const BBox* GetBox() const { return (BBox*) getBox(); }
+    double GetMinSize() { return getData()->myMinSize; }
+  };
+  //================================================================================
+  /*!
+   * \brief Data of triangle used to locate it in an octree and to find distance
+   *        to a point
+   */
+  struct Triangle
+  {
+    Bnd_B3d myBox;
+    // data for DistToProjection()
+    gp_XYZ myN0, myEdge1, myEdge2, myNorm, myPVec;
+    double myInvDet, myMaxSize2;
+
+    void Init( const gp_Pnt& n1, const gp_Pnt& n2, const gp_Pnt& n3 ); 
+    bool DistToProjection( const gp_Pnt& p, double& dist ) const;
+  };
+  //================================================================================
+  /*!
+   * \brief Element data held by ElementBndBoxTree + algorithm computing a distance
+   *        from a point to element
+   */
+  class ElementBndBoxTree;
+  struct ElemTreeData : public SMESH_TreeLimit
+  {
+    virtual const Bnd_B3d* GetBox(int elemID) const = 0;
+  };
+  struct TriaTreeData : public ElemTreeData
+  {
+    vector< Triangle >           myTrias;
+    double                       myFaceTol;
+    double                       myTriasDeflection;
+    const ElementBndBoxTree*     myTree;
+    const Poly_Array1OfTriangle* myPolyTrias;
+    const TColgp_Array1OfPnt*    myNodes;
+    bool                         myOwnNodes;
+
+    TriaTreeData( const TopoDS_Face& face, ElementBndBoxTree* triaTree );
+    ~TriaTreeData() { if ( myOwnNodes ) delete myNodes; myNodes = NULL; }
+    virtual const Bnd_B3d* GetBox(int elemID) const { return &myTrias[elemID].myBox; }
+    void SetSizeByTrias( SegSizeTree& sizeTree, double deflection ) const;
+    double GetMinDistInSphere(const gp_Pnt& p,
+                              const double  radius,
+                              const bool    projectedOnly,
+                              const gp_Pnt* avoidP=0) const;
+  };
+  //================================================================================
+  /*!
+   * \brief Octree of triangles or segments
+   */
+  class ElementBndBoxTree : public SMESH_Octree
+  {
+  public:
+    ElementBndBoxTree(const TopoDS_Face& face);
+    void GetElementsInSphere( const gp_XYZ& center,
+                              const double  radius, std::set<int> & foundElemIDs) const;
+    ElemTreeData* GetElemData() const { return (ElemTreeData*) myLimit; }
+    TriaTreeData* GetTriaData() const { return (TriaTreeData*) myLimit; }
+
+  protected:
+    ElementBndBoxTree() {}
+    SMESH_Octree* newChild() const { return new ElementBndBoxTree; }
+    void          buildChildrenData();
+    Bnd_B3d*      buildRootBox();
+  private:
+    vector< int > _elementIDs;
+  };
+  //================================================================================
+  /*!
+   * \brief BRepMesh_IncrementalMesh with access to its protected Bnd_Box
+   */
+  struct IncrementalMesh : public BRepMesh_IncrementalMesh
+  {
+    IncrementalMesh(const TopoDS_Shape& shape,
+                    const Standard_Real deflection,
+                    const bool          relative):
+      BRepMesh_IncrementalMesh( shape, deflection, relative )
+    {
+    }
+    Bnd_B3d GetBox() const
+    {
+      Standard_Real TXmin, TYmin, TZmin, TXmax, TYmax, TZmax;
+      myBox.Get(TXmin, TYmin, TZmin, TXmax, TYmax, TZmax);
+      Bnd_B3d bb;
+      bb.Add( gp_XYZ( TXmin, TYmin, TZmin ));
+      bb.Add( gp_XYZ( TXmax, TYmax, TZmax ));
+      return bb;
+    }
+  };
+
+  //================================================================================
+  /*!
+   * \brief Initialize TriaTreeData
+   */
+  //================================================================================
+
+  TriaTreeData::TriaTreeData( const TopoDS_Face& face, ElementBndBoxTree* triaTree )
+    : myTree(NULL), myPolyTrias(NULL), myNodes(NULL), myOwnNodes(false), myTriasDeflection(0)
+  {
+    TopLoc_Location loc;
+    Handle(Poly_Triangulation) tr = BRep_Tool::Triangulation( face, loc );
+    if ( !tr.IsNull() )
+    {
+      myFaceTol         = SMESH_MesherHelper::MaxTolerance( face );
+      myTree            = triaTree;
+      myNodes           = & tr->Nodes();
+      myPolyTrias       = & tr->Triangles();
+      myTriasDeflection = tr->Deflection();
+      if ( !loc.IsIdentity() ) // transform nodes if necessary
+      {
+        TColgp_Array1OfPnt* trsfNodes = new TColgp_Array1OfPnt( myNodes->Lower(), myNodes->Upper() );
+        trsfNodes->Assign( *myNodes );
+        myNodes    = trsfNodes;
+        myOwnNodes = true;
+        const gp_Trsf& trsf = loc;
+        for ( int i = trsfNodes->Lower(); i <= trsfNodes->Upper(); ++i )
+          trsfNodes->ChangeValue(i).Transform( trsf );
+      }
+      myTrias.resize( myPolyTrias->Length() );
+      Standard_Integer n1,n2,n3;
+      for ( int i = 1; i <= myPolyTrias->Upper(); ++i )
+      {
+        myPolyTrias->Value( i ).Get( n1,n2,n3 );
+        myTrias[ i-1 ].Init( myNodes->Value( n1 ),
+                             myNodes->Value( n2 ),
+                             myNodes->Value( n3 ));
+      }
+      // TODO: mark triangles with nodes on VERTEXes to
+      // less frequently compare with avoidPnt in GetMinDistInSphere()
+      //
+      // Handle(Poly_PolygonOnTriangulation) polygon =
+      //   BRep_Tool::PolygonOnTriangulation( edge, tr, loc );
+      // if ( polygon.IsNull() /*|| !pologon.HasParameters()*/ )
+      //   continue;
+      // Handle(TColStd_Array1OfInteger) nodeIDs = polygon->Nodes();
+    }
+  }
+  //================================================================================
+  /*!
+   * \brief Set size of segments by size of triangles
+   */
+  //================================================================================
+
+  void TriaTreeData::SetSizeByTrias( SegSizeTree& sizeTree, double deflection ) const
+  {
+    if ( myTriasDeflection <= std::numeric_limits<double>::min() )
+      return;
+    const double factor = deflection / myTriasDeflection;
+
+    Standard_Integer n1,n2,n3;
+    gp_Pnt p[4];
+    double a[3];
+    for ( int i = 1; i <= myPolyTrias->Upper(); ++i )
+    {
+      // compute minimal altitude of a triangle
+      myPolyTrias->Value( i ).Get( n1,n2,n3 );
+      p[0] = myNodes->Value( n1 );
+      p[1] = myNodes->Value( n2 );
+      p[2] = myNodes->Value( n3 );
+      p[3] = p[0];
+      a[0] = p[0].Distance( p[1] );
+      a[1] = p[1].Distance( p[2] );
+      a[2] = p[2].Distance( p[3] );
+      double maxSide = Max( a[0], Max( a[1], a[2] ));
+      double s       = 0.5 * ( a[0] + a[1] + a[2] );
+      double area    = sqrt( s * (s - a[0]) * (s - a[1]) * (s - a[2]));
+      double sz      = 2 * area / maxSide; // minimal altitude
+      for ( int j = 0; j < 3; ++j )
+      {
+        int nb = 2 * int( a[j] / sz + 0.5 );
+        for ( int k = 1; k <= nb; ++k )
+        {
+          double r = double( k ) / nb;
+          sizeTree.SetSize( r * p[j].XYZ() + ( 1-r ) * p[j+1].XYZ(), sz * factor );
+        }
+      }
+      sizeTree.SetSize(( p[0].XYZ() + p[1].XYZ() + p[2].XYZ()) / 3., sz * factor );
+      //cout << "SetSizeByTrias, i="<< i << " " << sz * factor << endl;
+    }
+  }
+  //================================================================================
+  /*!
+   * \brief Return minimal distance from a given point to a trinangle but not more
+   *        distant than a given radius. Triangles with a node at avoidPnt are ignored.
+   *        If projectedOnly, 
+   */
+  //================================================================================
+
+  double TriaTreeData::GetMinDistInSphere(const gp_Pnt& p,
+                                          const double  radius,
+                                          const bool    projectedOnly,
+                                          const gp_Pnt* avoidPnt) const
+  {
+    double minDist2 = 1e100;
+    const double tol2 = myFaceTol * myFaceTol;
+
+    std::set<int> foundElemIDs;
+    myTree->GetElementsInSphere( p.XYZ(), radius, foundElemIDs );
+
+    std::set<int>::iterator id = foundElemIDs.begin();
+    Standard_Integer n[ 3 ];
+    for ( ; id != foundElemIDs.end(); ++id )
+    {
+      double d, minD2 = minDist2;
+      bool avoidTria = false;
+      myPolyTrias->Value( *id+1 ).Get( n[0],n[1],n[2] );
+      for ( int i = 0; i < 3; ++i )
+      {
+        const gp_Pnt& pn = myNodes->Value(n[i]);
+        if ( avoidTria = ( avoidPnt && pn.SquareDistance(*avoidPnt) <= tol2 ))
+          break;
+        if ( !projectedOnly )
+          minD2 = Min( minD2, pn.SquareDistance( p ));
+      }
+      if ( !avoidTria )
+      {
+        const Triangle& t = myTrias[ *id ];
+        if ( minD2 < t.myMaxSize2 && t.DistToProjection( p, d ))
+          minD2 = Min( minD2, d*d );
+        minDist2 = Min( minDist2, minD2 );
+      }
+    }
+    return sqrt( minDist2 );
+  }
+  //================================================================================
+  /*!
+   * \brief Prepare Triangle data
+   */
+  //================================================================================
+
+  void Triangle::Init( const gp_Pnt& p1, const gp_Pnt& p2, const gp_Pnt& p3 )
+  {
+    myBox.Add( p1 );
+    myBox.Add( p2 );
+    myBox.Add( p3 );
+    myN0 = p1.XYZ();
+    myEdge1 = p2.XYZ() - myN0;
+    myEdge2 = p3.XYZ() - myN0;
+    myNorm = myEdge1 ^ myEdge2;
+    double normSize = myNorm.Modulus();
+    if ( normSize > std::numeric_limits<double>::min() )
+    {
+      myNorm /= normSize;
+      myPVec = myNorm ^ myEdge2;
+      myInvDet = 1. / ( myEdge1 * myPVec );
+    }
+    else
+    {
+      myInvDet = 0.;
+    }
+    myMaxSize2 = Max( p2.SquareDistance( p3 ),
+                      Max( myEdge2.SquareModulus(), myEdge1.SquareModulus() ));
+  }
+  //================================================================================
+  /*!
+   * \brief Compute distance from a point to the triangle. Return false if the point
+   *        is not projected inside the triangle
+   */
+  //================================================================================
+
+  bool Triangle::DistToProjection( const gp_Pnt& p, double& dist ) const
+  {
+    if ( myInvDet == 0 )
+      return false; // degenerated triangle
+
+    /* distance from n0 to the point */
+    gp_XYZ tvec = p.XYZ() - myN0;
+
+    /* calculate U parameter and test bounds */
+    double u = ( tvec * myPVec ) * myInvDet;
+    if (u < 0.0 || u > 1.0)
+      return false; // projected outside the triangle
+
+    /* calculate V parameter and test bounds */
+    gp_XYZ qvec = tvec ^ myEdge1;
+    double v = ( myNorm * qvec) * myInvDet;
+    if ( v < 0.0 || u + v > 1.0 )
+      return false; // projected outside the triangle
+
+    dist = ( myEdge2 * qvec ) * myInvDet;
+    return true;
+  }
+
+  //================================================================================
+  /*!
+   * \brief Consturct ElementBndBoxTree of Poly_Triangulation of a FACE
+   */
+  //================================================================================
+
+  ElementBndBoxTree::ElementBndBoxTree(const TopoDS_Face& face)
+    :SMESH_Octree()
+  {
+    TriaTreeData* data = new TriaTreeData( face, this );
+    data->myMaxLevel = 5;
+    myLimit = data;
+
+    if ( !data->myTrias.empty() )
+    {
+      for ( size_t i = 0; i < data->myTrias.size(); ++i )
+        _elementIDs.push_back( i );
+
+      compute();
+    }
+  }
+  //================================================================================
+  /*!
+   * \brief Return the maximal box
+   */
+  //================================================================================
+
+  Bnd_B3d* ElementBndBoxTree::buildRootBox()
+  {
+    Bnd_B3d* box = new Bnd_B3d;
+    ElemTreeData* data = GetElemData();
+    for ( int i = 0; i < _elementIDs.size(); ++i )
+      box->Add( *data->GetBox( _elementIDs[i] ));
+    return box;
+  }
+
+  //================================================================================
+  /*!
+   * \brief Redistrubute element boxes among children
+   */
+  //================================================================================
+
+  void ElementBndBoxTree::buildChildrenData()
+  {
+    ElemTreeData* data = GetElemData();
+    for ( int i = 0; i < _elementIDs.size(); ++i )
+    {
+      const Bnd_B3d* elemBox = data->GetBox( _elementIDs[i] );
+      for (int j = 0; j < 8; j++)
+        if ( !elemBox->IsOut( *myChildren[j]->getBox() ))
+          ((ElementBndBoxTree*)myChildren[j])->_elementIDs.push_back( _elementIDs[i] );
+    }
+    SMESHUtils::FreeVector( _elementIDs ); // = _elements.clear() + free memory
+
+    const int theMaxNbElemsInLeaf = 7;
+
+    for (int j = 0; j < 8; j++)
+    {
+      ElementBndBoxTree* child = static_cast<ElementBndBoxTree*>( myChildren[j] );
+      if ( child->_elementIDs.size() <= theMaxNbElemsInLeaf )
+        child->myIsLeaf = true;
+    }
+  }
+  //================================================================================
+  /*!
+   * \brief Return elements from leaves intersecting the sphere
+   */
+  //================================================================================
+
+  void ElementBndBoxTree::GetElementsInSphere( const gp_XYZ&   center,
+                                               const double    radius,
+                                               std::set<int> & foundElemIDs) const
+  {
+    if ( const box_type* box = getBox() )
+    {
+      if ( box->IsOut( center, radius ))
+        return;
+
+      if ( isLeaf() )
+      {
+        ElemTreeData* data = GetElemData();
+        for ( int i = 0; i < _elementIDs.size(); ++i )
+          if ( !data->GetBox( _elementIDs[i] )->IsOut( center, radius ))
+            foundElemIDs.insert( _elementIDs[i] );
+      }
+      else
+      {
+        for (int i = 0; i < 8; i++)
+          ((ElementBndBoxTree*) myChildren[i])->GetElementsInSphere( center, radius, foundElemIDs );
+      }
+    }
+  }
+
+  //================================================================================
+  /*!
+   * \brief Constructor of SegSizeTree
+   *  \param [in,out] bb - bounding box enclosing all EDGEs to discretize 
+   *  \param [in] grading - factor to get max size of the neighbour segment by 
+   *         size of a current one.
+   */
+  //================================================================================
+
+  SegSizeTree::SegSizeTree( Bnd_B3d & bb, double grading, double minSize, double maxSize )
+    : SMESH_Octree( new _CommonData() )
+  {
+    // make cube myBox from the box bb
+    gp_XYZ pmin = bb.CornerMin(), pmax = bb.CornerMax();
+    double maxBoxHSize = 0.5 * Max( pmax.X()-pmin.X(), Max( pmax.Y()-pmin.Y(), pmax.Z()-pmin.Z() ));
+    maxBoxHSize *= 1.01;
+    bb.SetHSize( gp_XYZ( maxBoxHSize, maxBoxHSize, maxBoxHSize ));
+    myBox = new box_type( bb );
+
+    mySegSize = Min( 2 * maxBoxHSize, maxSize );
+
+    getData()->myGrading = grading;
+    getData()->myMinSize = Max( minSize, 2*maxBoxHSize / 1.e6 );
+    getData()->myMaxSize = maxSize;
+    allocateChildren();
+  }
+
+  //================================================================================
+  /*!
+   * \brief Set segment size at a given point
+   */
+  //================================================================================
+
+  void SegSizeTree::SetSize( const gp_Pnt& p, double size )
+  {
+    // check if the point is out of the largest cube
+    SegSizeTree* root = this;
+    while ( root->myFather )
+      root = (SegSizeTree*) root->myFather;
+    if ( root->getBox()->IsOut( p.XYZ() ))
+      return;
+
+    // keep size whthin the valid range
+    size = Max( size, getData()->myMinSize );
+    //size = Min( size, getData()->myMaxSize );
+
+    // find an existing leaf at the point
+    SegSizeTree* leaf = (SegSizeTree*) root;
+    int iChild;
+    while ( true )
+    {
+      iChild = SMESH_Octree::getChildIndex( p.X(), p.Y(), p.Z(), leaf->GetBox()->Center() );
+      if ( leaf->myChildren[ iChild ] )
+        leaf = (SegSizeTree*) leaf->myChildren[ iChild ];
+      else
+        break;
+    }
+    // don't increase the current size
+    if ( leaf->mySegSize <= 1.1 * size )
+      return;
+
+    // split the found leaf until its box size is less than the given size
+    const double rootSize = root->GetBox()->Size();
+    while ( leaf->GetBox()->Size() > size )
+    {
+      const BBox* bb = leaf->GetBox();
+      iChild   = SMESH_Octree::getChildIndex( p.X(), p.Y(), p.Z(), bb->Center() );
+      SegSizeTree* newLeaf = new SegSizeTree( bb->Size() / 2 );
+      leaf->myChildren[iChild] = newLeaf;
+      newLeaf->myFather = leaf;
+      newLeaf->myLimit  = leaf->myLimit;
+      newLeaf->myLevel  = leaf->myLevel + 1;
+      newLeaf->myBox    = leaf->newChildBox( iChild );
+      newLeaf->myBox->Enlarge( rootSize * 1e-10 );
+      //newLeaf->myIsLeaf = ( newLeaf->mySegSize <= size );
+      leaf = newLeaf;
+    }
+    leaf->mySegSize = size;
+
+    // propagate increased size out from the leaf
+    double boxSize = leaf->GetBox()->Size();
+    double sizeInc = size + boxSize * getData()->myGrading;
+    for ( int iDir = 1; iDir <= 3; ++iDir )
+    {
+      gp_Pnt outPnt = p;
+      outPnt.SetCoord( iDir, p.Coord( iDir ) + boxSize );
+      SetSize( outPnt, sizeInc );
+      outPnt.SetCoord( iDir, p.Coord( iDir ) - boxSize );
+      SetSize( outPnt, sizeInc );
+    }
+  }
+  //================================================================================
+  /*!
+   * \brief Set size of a segment given by two end points
+   */
+  //================================================================================
+
+  double SegSizeTree::SetSize( const gp_Pnt& p1, const gp_Pnt& p2 )
+  {
+    const double size = p1.Distance( p2 );
+    gp_XYZ p = 0.5 * ( p1.XYZ() + p2.XYZ() );
+    SetSize( p, size );
+    SetSize( p1, size );
+    SetSize( p2, size );
+    //cout << "SetSize " << p1.Distance( p2 ) << " at " << p.X() <<", "<< p.Y()<<", "<<p.Z()<< endl;
+    return GetSize( p );
+  }
+
+  //================================================================================
+  /*!
+   * \brief Return segment size at a point
+   */
+  //================================================================================
+
+  double SegSizeTree::GetSize( const gp_Pnt& p ) const
+  {
+    const SegSizeTree* leaf = this;
+    while ( true )
+    {
+      int iChild = SMESH_Octree::getChildIndex( p.X(), p.Y(), p.Z(), leaf->GetBox()->Center() );
+      if ( leaf->myChildren[ iChild ] )
+        leaf = (SegSizeTree*) leaf->myChildren[ iChild ];
+      else
+        return leaf->mySegSize;
+    }
+    return mySegSize; // just to return anything
+  }
+
+  //================================================================================
+  /*!
+   * \brief Evaluate curve deflection between two points
+   * \param theCurve - the curve
+   * \param theU1 - the parameter of the first point
+   * \param theU2 - the parameter of the second point
+   * \retval double - square deflection value
+   */
+  //================================================================================
+
+  double deflection2(const BRepAdaptor_Curve & theCurve,
+                     double                    theU1,
+                     double                    theU2)
+  {
+    // line between theU1 and theU2
+    gp_Pnt p1 = theCurve.Value( theU1 ), p2 = theCurve.Value( theU2 );
+    gp_Lin segment( p1, gp_Vec( p1, p2 ));
+
+    // evaluate square distance of theCurve from the segment
+    Standard_Real dist2 = 0;
+    const int nbPnt = 5;
+    const double step = ( theU2 - theU1 ) / nbPnt;
+    while (( theU1 += step ) < theU2 )
+      dist2 = Max( dist2, segment.SquareDistance( theCurve.Value( theU1 )));
+
+    return dist2;
+  }
+
+} // namespace
+
+//=======================================================================
+//function : StdMeshers_Adaptive1D
+//purpose  : Constructor
+StdMeshers_Adaptive1D::StdMeshers_Adaptive1D(int         hypId,
+                                             int         studyId,
+                                             SMESH_Gen * gen)
+  :SMESH_Hypothesis(hypId, studyId, gen)
+{
+  myMinSize       = 1e-10;
+  myMaxSize       = 1e+10;
+  myDeflection    = 1e-2;
+  myAlgo          = NULL;
+  _name           = "Adaptive1D";
+  _param_algo_dim = 1; // is used by SMESH_Regular_1D
+}
+//=======================================================================
+//function : ~StdMeshers_Adaptive1D
+//purpose  : Destructor
+StdMeshers_Adaptive1D::~StdMeshers_Adaptive1D()
+{
+  delete myAlgo; myAlgo = NULL;
+}
+//=======================================================================
+//function : SetDeflection
+//purpose  : 
+void StdMeshers_Adaptive1D::SetDeflection(double value)
+  throw(SALOME_Exception)
+{
+  if (value <= std::numeric_limits<double>::min() )
+    throw SALOME_Exception("Deflection must be greater that zero");
+  if (myDeflection != value)
+  {
+    myDeflection = value;
+    NotifySubMeshesHypothesisModification();
+  }
+}
+//=======================================================================
+//function : SetMinSize
+//purpose  : Sets minimal allowed segment length
+void StdMeshers_Adaptive1D::SetMinSize(double minSize)
+  throw(SALOME_Exception)
+{
+  if (minSize <= std::numeric_limits<double>::min() )
+    throw SALOME_Exception("Min size must be greater that zero");
+
+  if (myMinSize != minSize )
+  {
+    myMinSize = minSize;
+    NotifySubMeshesHypothesisModification();
+  }
+}
+//=======================================================================
+//function : SetMaxSize
+//purpose  : Sets maximal allowed segment length
+void StdMeshers_Adaptive1D::SetMaxSize(double maxSize)
+  throw(SALOME_Exception)
+{
+  if (maxSize <= std::numeric_limits<double>::min() )
+    throw SALOME_Exception("Max size must be greater that zero");
+
+  if (myMaxSize != maxSize )
+  {
+    myMaxSize = maxSize;
+    NotifySubMeshesHypothesisModification();
+  }
+}
+//=======================================================================
+//function : SaveTo
+//purpose  : Persistence
+ostream & StdMeshers_Adaptive1D::SaveTo(ostream & save)
+{
+  save << myMinSize << " " << myMaxSize << " " << myDeflection;
+  save << " " << -1 << " " << -1; // preview addition of parameters
+  return save;
+}
+//=======================================================================
+//function : LoadFrom
+//purpose  : Persistence
+istream & StdMeshers_Adaptive1D::LoadFrom(istream & load)
+{
+  int dummyParam;
+  bool isOK = (load >> myMinSize >> myMaxSize >> myDeflection >> dummyParam >> dummyParam);
+  if (!isOK)
+    load.clear(ios::badbit | load.rdstate());
+  return load;
+}
+//=======================================================================
+//function : SetParametersByMesh
+//purpose  : Initialize parameters by the mesh built on the geometry
+//param theMesh - the built mesh
+//param theShape - the geometry of interest
+//retval bool - true if parameter values have been successfully defined
+bool StdMeshers_Adaptive1D::SetParametersByMesh(const SMESH_Mesh*   theMesh,
+                                                const TopoDS_Shape& theShape)
+{
+  if ( !theMesh || theShape.IsNull() )
+    return false;
+
+  int nbEdges = 0;
+  TopTools_IndexedMapOfShape edgeMap;
+  TopExp::MapShapes( theShape, TopAbs_EDGE, edgeMap );
+
+  SMESH_MesherHelper helper( (SMESH_Mesh&) *theMesh );
+  double minSz2 = 1e100, maxSz2 = 0, sz2, maxDefl2 = 0;
+  for ( int iE = 1; iE <= edgeMap.Extent(); ++iE )
+  {
+    const TopoDS_Edge& edge = TopoDS::Edge( edgeMap( iE ));
+    SMESHDS_SubMesh* smDS = theMesh->GetMeshDS()->MeshElements( edge );
+    if ( !smDS ) continue;
+    ++nbEdges;
+
+    helper.SetSubShape( edge );
+    BRepAdaptor_Curve curve( edge );
+
+    SMDS_ElemIteratorPtr segIt = smDS->GetElements();
+    while ( segIt->more() )
+    {
+      const SMDS_MeshElement* seg = segIt->next();
+      const SMDS_MeshNode* n1 = seg->GetNode(0);
+      const SMDS_MeshNode* n2 = seg->GetNode(1);
+      sz2 = SMESH_TNodeXYZ( n1 ).SquareDistance( n2 );
+      minSz2 = Min( minSz2, sz2 );
+      maxSz2 = Max( maxSz2, sz2 );
+      if ( curve.GetType() != GeomAbs_Line )
+      {
+        double u1 = helper.GetNodeU( edge, n1, n2 );
+        double u2 = helper.GetNodeU( edge, n2, n1 );
+        maxDefl2 = Max( maxDefl2, deflection2( curve, u1, u2 ));
+      }
+    }
+  }
+  if ( nbEdges )
+  {
+    myMinSize = sqrt( minSz2 );
+    myMaxSize = sqrt( maxSz2 );
+    if ( maxDefl2 > 0 )
+      myDeflection = maxDefl2;
+  }
+  return nbEdges;
+}
+
+//=======================================================================
+//function : SetParametersByDefaults
+//purpose  : Initialize my parameter values by default parameters.
+//retval   : bool - true if parameter values have been successfully defined
+bool StdMeshers_Adaptive1D::SetParametersByDefaults(const TDefaults&  dflts,
+                                                    const SMESH_Mesh* /*theMesh*/)
+{
+  myMinSize = dflts._elemLength / 100;
+  myMaxSize = dflts._elemLength * 2;
+  myDeflection = myMinSize / 10;
+  return true;
+}
+
+//=======================================================================
+//function : GetAlgo
+//purpose  : Returns an algorithm that works using this hypothesis
+//=======================================================================
+
+StdMeshers_AdaptiveAlgo_1D* StdMeshers_Adaptive1D::GetAlgo() const
+{
+  if ( !myAlgo )
+  {
+    StdMeshers_AdaptiveAlgo_1D* newAlgo = 
+      new StdMeshers_AdaptiveAlgo_1D( _gen->GetANewId(), _studyId, _gen );
+    newAlgo->SetHypothesis( this );
+
+    ((StdMeshers_Adaptive1D*) this)->myAlgo = newAlgo;
+  }
+  return myAlgo;
+}
+
+//================================================================================
+/*!
+ * \brief Constructor
+ */
+//================================================================================
+
+StdMeshers_AdaptiveAlgo_1D::StdMeshers_AdaptiveAlgo_1D(int        hypId,
+                                                       int        studyId,
+                                                       SMESH_Gen* gen)
+  : StdMeshers_Regular_1D( hypId, studyId, gen ),
+    myHyp(NULL)
+{
+  _name = "AdaptiveAlgo_1D";
+}
+
+//================================================================================
+/*!
+ * \brief Sets the hypothesis
+ */
+//================================================================================
+
+void StdMeshers_AdaptiveAlgo_1D::SetHypothesis( const StdMeshers_Adaptive1D* hyp )
+{
+  myHyp = hyp;
+}
+
+//================================================================================
+/*!
+ * \brief Creates segments on all given EDGEs
+ */
+//================================================================================
+
+bool StdMeshers_AdaptiveAlgo_1D::Compute(SMESH_Mesh &         theMesh,
+                                         const TopoDS_Shape & theShape,
+                                         double*              theProgress,
+                                         int*                 theProgressTic)
+{
+  *theProgress = 0.01;
+
+  if ( myHyp->GetMinSize() > myHyp->GetMaxSize() )
+    return error( "Bad parameters: min size > max size" );
+
+  SMESH_MesherHelper helper( theMesh );
+  const double grading = 0.7;
+
+  TopTools_IndexedMapOfShape edgeMap, faceMap;
+  TopExp::MapShapes( theShape,                 TopAbs_EDGE, edgeMap );
+  TopExp::MapShapes( theMesh.GetShapeToMesh(), TopAbs_FACE, faceMap );
+
+  // Triangulate the shape with the given deflection ?????????
+  Bnd_B3d box;
+  {
+    IncrementalMesh im( theMesh.GetShapeToMesh(), myHyp->GetDeflection(), /*Relatif=*/false);
+    box = im.GetBox();
+  }
+  *theProgress = 0.3;
+
+  // holder of segment size at each point
+  SegSizeTree sizeTree( box, grading, myHyp->GetMinSize(), myHyp->GetMaxSize() );
+
+  // minimal segment size that sizeTree can store with reasonable tree height
+  const double minSize = Max( myHyp->GetMinSize(), 1.1 * sizeTree.GetMinSize() );
+
+
+  // working data of EDGEs
+  vector< EdgeData > edges;
+  {
+    // sort EDGEs by length
+    multimap< double, TopoDS_Edge > edgeOfLength;
+    for ( int iE = 1; iE <= edgeMap.Extent(); ++iE )
+    {
+      const TopoDS_Edge & edge = TopoDS::Edge( edgeMap( iE ));
+      if ( !SMESH_Algo::isDegenerated( edge) )
+        edgeOfLength.insert( make_pair( EdgeLength( edge ), edge ));
+    }
+    edges.resize( edgeOfLength.size() );
+    multimap< double, TopoDS_Edge >::const_iterator len2edge = edgeOfLength.begin();
+    for ( int iE = 0; len2edge != edgeOfLength.end(); ++len2edge, ++iE )
+    {
+      const TopoDS_Edge & edge = len2edge->second;
+      EdgeData& eData = edges[ iE ];
+      eData.myC3d.Initialize( edge );
+      eData.myLength  = EdgeLength( edge );
+      eData.AddPoint( eData.myPoints.end(), eData.myC3d.FirstParameter() );
+      eData.AddPoint( eData.myPoints.end(), eData.myC3d.LastParameter() );
+    }
+  }
+
+  // Take into account size of already existing segments
+  SMDS_EdgeIteratorPtr segIterator = theMesh.GetMeshDS()->edgesIterator();
+  while ( segIterator->more() )
+  {
+    const SMDS_MeshElement* seg = segIterator->next();
+    sizeTree.SetSize( SMESH_TNodeXYZ( seg->GetNode( 0 )), SMESH_TNodeXYZ( seg->GetNode( 1 )));
+  }
+
+  // Set size of segments according to the deflection
+
+  StdMeshers_Regular_1D::_hypType = DEFLECTION;
+  StdMeshers_Regular_1D::_value[ DEFLECTION_IND ] = myHyp->GetDeflection();
+
+  list< double > params;
+  for ( int iE = 0; iE < edges.size(); ++iE )
+  {
+    EdgeData& eData = edges[ iE ];
+    //cout << "E " << theMesh.GetMeshDS()->ShapeToIndex( eData.Edge() ) << endl;
+
+    double f = eData.First().myU, l = eData.Last().myU;
+    if ( !computeInternalParameters( theMesh, eData.myC3d, eData.myLength, f,l, params, false, false ))
+      continue;
+    if ( params.size() <= 1 && helper.IsClosedEdge( eData.Edge() ) ) // 2 segments on a circle
+    {
+      params.clear();
+      for ( int i = 1; i < 6; ++i )
+        params.push_back(( l - f ) * i/6. );
+    }
+    EdgeData::TPntIter where = --eData.myPoints.end();
+    list< double >::const_iterator param = params.begin();
+    for ( ; param != params.end(); ++param )
+      eData.AddPoint( where, *param );
+
+    EdgeData::TPntIter pIt2 = eData.myPoints.begin(), pIt1 = pIt2++;
+    for ( ; pIt2 != eData.myPoints.end(); ++pIt1, ++pIt2 )
+      sizeTree.SetSize( (*pIt1).myP, (*pIt2).myP );
+  }
+
+  // Limit size of segments according to distance to closest FACE
+
+  for ( int iF = 1; iF <= faceMap.Extent(); ++iF )
+  {
+    const TopoDS_Face & face = TopoDS::Face( faceMap( iF ));
+    // cout << "FACE " << iF << "/" << faceMap.Extent()
+    //      << " id-" << theMesh.GetMeshDS()->ShapeToIndex( face ) << endl;
+
+    ElementBndBoxTree triaTree( face ); // tree of FACE triangulation
+    TriaTreeData*     triaSearcher = triaTree.GetTriaData();
+
+    if ( BRepAdaptor_Surface( face ).GetType() != GeomAbs_Plane )
+      triaSearcher->SetSizeByTrias( sizeTree, myHyp->GetDeflection() );
+
+    for ( int iE = 0; iE < edges.size(); ++iE )
+    {
+      EdgeData& eData = edges[ iE ];
+
+      // check if the face is in topological contact with the edge
+      bool isAdjFace = ( helper.IsSubShape( helper.IthVertex( 0, eData.Edge()), face ) ||
+                         helper.IsSubShape( helper.IthVertex( 1, eData.Edge()), face ));
+
+      bool sizeDecreased = true;
+      for (int iLoop = 0; sizeDecreased; ++iLoop ) //repeat until segment size along the edge becomes stable
+      {
+        // get points to check distance to the face
+        EdgeData::TPntIter pIt2 = eData.myPoints.begin(), pIt1 = pIt2++;
+        pIt1->mySegSize = sizeTree.GetSize( pIt1->myP );
+        for ( ; pIt2 != eData.myPoints.end(); )
+        {
+          pIt2->mySegSize = sizeTree.GetSize( pIt2->myP );
+          double curSize = Min( pIt1->mySegSize, pIt2->mySegSize );
+          if ( pIt1->myP.Distance( pIt2->myP ) > curSize )
+          {
+            double midU  = 0.5*( pIt1->myU + pIt2->myU );
+            gp_Pnt midP  = eData.myC3d.Value( midU );
+            double midSz = sizeTree.GetSize( midP );
+            pIt2 = eData.myPoints.insert( pIt2, EdgeData::ProbePnt( midP, midU, midSz ));
+          }
+          else
+          {
+            ++pIt1, ++pIt2;
+          }
+        }
+        // check if the face is more distant than a half of the current segment size,
+        // if not, segment size is decreased
+        sizeDecreased = false;
+        const gp_Pnt* avoidPnt = & eData.First().myP;
+        for ( pIt1 = eData.myPoints.begin(); pIt1 != eData.myPoints.end();  )
+        {
+          double distToFace =
+            triaSearcher->GetMinDistInSphere( pIt1->myP, pIt1->mySegSize, isAdjFace, avoidPnt );
+          double allowedSize = Max( minSize, distToFace*( 1. + grading ));
+          if ( 1.1 * allowedSize < pIt1->mySegSize  )
+          {
+            sizeDecreased = true;
+            sizeTree.SetSize( pIt1->myP, allowedSize );
+            // cout << "E " << theMesh.GetMeshDS()->ShapeToIndex( eData.Edge() )
+            //      << "\t SetSize " << allowedSize << " at "
+            //      << pIt1->myP.X() <<", "<< pIt1->myP.Y()<<", "<<pIt1->myP.Z() << endl;
+            pIt2 = pIt1;
+            if ( --pIt2 != eData.myPoints.end() && pIt2->mySegSize > allowedSize )
+              sizeTree.SetSize( eData.myC3d.Value( 0.6*pIt2->myU + 0.4*pIt1->myU ), allowedSize );
+            pIt2 = pIt1;
+            if ( ++pIt2 != eData.myPoints.end() && pIt2->mySegSize > allowedSize )
+              sizeTree.SetSize( eData.myC3d.Value( 0.6*pIt2->myU + 0.4*pIt1->myU ), allowedSize );
+            pIt1->mySegSize = allowedSize;
+          }
+          ++pIt1;
+          if ( & (*pIt1) == & eData.Last() )
+            avoidPnt = & eData.Last().myP;
+          else
+            avoidPnt = NULL;
+
+          if ( iLoop > 20 )
+          {
+#ifdef _DEBUG_
+            cout << "Infinite loop in StdMeshers_AdaptiveAlgo_1D::Compute()" << endl;
+#endif
+            sizeDecreased = false;
+            break;
+          }
+        }
+      } // while ( sizeDecreased )
+    } // loop on edges
+
+    *theProgress = 0.3 + 0.3 * iF / double( faceMap.Extent() );
+    if ( _computeCanceled )
+      return false;
+
+  } // loop on faceMap
+
+
+  // Create segments
+
+  SMESH_HypoFilter quadHyp( SMESH_HypoFilter::HasName( "QuadraticMesh" ));
+  _quadraticMesh = theMesh.GetHypothesis( edges[0].Edge(), quadHyp, /*andAncestors=*/true );
+  helper.SetIsQuadratic( _quadraticMesh );
+
+  for ( int iE = 0; iE < edges.size(); ++iE )
+  {
+    EdgeData& eData = edges[ iE ];
+
+    // estimate roughly min segement size on the EDGE
+    double edgeMinSize = myHyp->GetMaxSize();
+    EdgeData::TPntIter pIt1 = eData.myPoints.begin();
+    for ( ; pIt1 != eData.myPoints.end(); ++pIt1 )
+      edgeMinSize = Min( edgeMinSize, sizeTree.GetSize( pIt1->myP ));
+
+    const double f = eData.myC3d.FirstParameter(), l = eData.myC3d.LastParameter();
+    const double parLen = l - f;
+    const int  nbDivSeg = 5;
+    int           nbDiv = int ( eData.myLength / edgeMinSize * nbDivSeg );
+
+    // compute nb of segments
+    vector< double > nbSegs;
+    bool toRecompute = true;
+    double maxSegSize = 0;
+    //cout << "E " << theMesh.GetMeshDS()->ShapeToIndex( eData.Edge() ) << endl;
+    while ( toRecompute ) // recompute if segment size at some point is less than edgeMinSize/nbDivSeg
+    {
+      nbSegs.resize( nbDiv + 1 );
+      nbSegs[0] = 0;
+      toRecompute = false;
+
+      gp_Pnt p1 = eData.First().myP, p2, pDiv = p1;
+      for ( size_t i = 1, segCount = 1; i < nbSegs.size(); ++i )
+      {
+        p2 = eData.myC3d.Value( f + parLen * i / nbDiv );
+        double locSize = Min( sizeTree.GetSize( p2 ), myHyp->GetMaxSize() );
+        double nb      = p1.Distance( p2 ) / locSize;
+        // if ( nbSegs.size() < 30 )
+        //   cout << "locSize " << locSize << " nb " << nb << endl;
+        if ( nb > 1. )
+        {
+          toRecompute = true;
+          edgeMinSize = locSize;
+          nbDiv = int ( eData.myLength / edgeMinSize * nbDivSeg );
+          break;
+        }
+        nbSegs[i] = nbSegs[i-1] + nb;
+        p1 = p2;
+        if ( nbSegs[i] >= segCount )
+        {
+          maxSegSize = Max( maxSegSize, pDiv.Distance( p2 ));
+          pDiv = p2;
+          ++segCount;
+        }
+      }
+    }
+
+    // compute parameters of nodes
+    int nbSegFinal = int(floor(nbSegs.back()+0.5));
+    double fact = nbSegFinal / nbSegs.back();
+    if ( maxSegSize / fact > myHyp->GetMaxSize() )
+      fact = ++nbSegFinal / nbSegs.back();
+    //cout << "nbSegs.back() " << nbSegs.back() << " nbSegFinal " << nbSegFinal << endl;
+    params.clear();
+    for ( int i = 0, segCount = 1; segCount < nbSegFinal; ++segCount )
+    {
+      while ( nbSegs[i] * fact < segCount )
+        ++i;
+      if ( i < nbDiv )
+        params.push_back( f + parLen * i / nbDiv );
+      else
+        break;
+    }
+    // get nodes on VERTEXes
+    TopoDS_Vertex vf = helper.IthVertex( 0, eData.Edge(), false );
+    TopoDS_Vertex vl = helper.IthVertex( 1, eData.Edge(), false );
+    theMesh.GetSubMesh( vf )->ComputeStateEngine( SMESH_subMesh::COMPUTE );
+    theMesh.GetSubMesh( vl )->ComputeStateEngine( SMESH_subMesh::COMPUTE );
+    const SMDS_MeshNode * nf = VertexNode( vf, theMesh.GetMeshDS() );
+    const SMDS_MeshNode * nl = VertexNode( vl, theMesh.GetMeshDS() );
+    if ( !nf || !nl )
+      return error("No node on vertex");
+
+    // create segments
+    helper.SetSubShape( eData.Edge() );
+    helper.SetElementsOnShape( true );
+    const int ID = 0;
+    const SMDS_MeshNode *n1 = nf, *n2;
+    list< double >::const_iterator u = params.begin();
+    for ( ; u != params.end(); ++u, n1 = n2 )
+    {
+      gp_Pnt p2 = eData.myC3d.Value( *u );
+      n2 = helper.AddNode( p2.X(), p2.Y(), p2.Z(), ID, *u );
+      helper.AddEdge( n1, n2, ID, /*force3d=*/false );
+    }
+    helper.AddEdge( n1, nl, ID, /*force3d=*/false );
+
+    *theProgress = 0.6 + 0.4 * iE / double( edges.size() );
+    if ( _computeCanceled )
+      return false;
+
+  } // loop on EDGEs
+
+}
+
+
+//================================================================================
+/*!
+ * \brief Creates segments on all given EDGEs
+ */
+//================================================================================
+
+bool StdMeshers_AdaptiveAlgo_1D::Evaluate(SMESH_Mesh &         theMesh,
+                                          const TopoDS_Shape & theShape,
+                                          MapShapeNbElems&     theResMap)
+{
+  // initialize fields of inherited StdMeshers_Regular_1D
+  StdMeshers_Regular_1D::_hypType = DEFLECTION;
+  StdMeshers_Regular_1D::_value[ DEFLECTION_IND ] = myHyp->GetDeflection();
+
+  TopExp_Explorer edExp( theShape, TopAbs_EDGE );
+
+  for ( ; edExp.More(); edExp.Next() )
+  {
+    const TopoDS_Edge & edge = TopoDS::Edge( edExp.Current() );
+    StdMeshers_Regular_1D::Evaluate( theMesh, theShape, theResMap );
+  }
+  return true;
+}
+    
diff --git a/src/StdMeshers/StdMeshers_Adaptive1D.hxx b/src/StdMeshers/StdMeshers_Adaptive1D.hxx
new file mode 100644 (file)
index 0000000..be5e329
--- /dev/null
@@ -0,0 +1,115 @@
+// Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//  File   : StdMeshers_Adaptive1D.hxx
+//  Module : SMESH
+//
+#ifndef _StdMeshers_Adaptive1D_HXX_
+#define _StdMeshers_Adaptive1D_HXX_
+
+#include "SMESH_StdMeshers.hxx"
+
+#include "StdMeshers_Regular_1D.hxx"
+
+#include "Utils_SALOME_Exception.hxx"
+
+class StdMeshers_AdaptiveAlgo_1D;
+
+/*!
+ * \brief Adaptive 1D hypothesis
+ */
+class STDMESHERS_EXPORT StdMeshers_Adaptive1D : public SMESH_Hypothesis
+{
+ public:
+  StdMeshers_Adaptive1D(int hypId, int studyId, SMESH_Gen * gen);
+  ~StdMeshers_Adaptive1D();
+
+  /*!
+   * Sets minimal allowed segment length
+   */
+  void SetMinSize( double minSegLen ) throw (SALOME_Exception);
+  double GetMinSize() const { return myMinSize; }
+
+  /*!
+   * Sets maximal allowed segment length
+   */
+  void SetMaxSize( double maxSegLen ) throw (SALOME_Exception);
+  double GetMaxSize() const { return myMaxSize; }
+
+  /*!
+   * Sets <deflection> parameter value, 
+   * i.e. a maximal allowed distance between a segment and an edge.
+   */
+  void SetDeflection(double value) throw(SALOME_Exception);
+  double GetDeflection() const { return myDeflection; }
+  
+  virtual std::ostream & SaveTo(std::ostream & save);
+  virtual std::istream & LoadFrom(std::istream & load);
+
+  /*!
+   * \brief Initialize deflection value by the mesh built on the geometry
+    * \param theMesh - the built mesh
+    * \param theShape - the geometry of interest
+    * \retval bool - true if parameter values have been successfully defined
+   */
+  virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape);
+
+  /*!
+   * \brief Initialize my parameter values by default parameters.
+   *  \retval bool - true if parameter values have been successfully defined
+   */
+  virtual bool SetParametersByDefaults(const TDefaults& dflts, const SMESH_Mesh* theMesh=0);
+
+  /*!
+   * \brief Returns an algorithm that works using this hypothesis
+   */
+  StdMeshers_AdaptiveAlgo_1D* GetAlgo() const;
+
+protected:
+
+  double myMinSize, myMaxSize, myDeflection;
+  StdMeshers_AdaptiveAlgo_1D* myAlgo;
+};
+
+/*!
+ * \brief Adaptive wire discertizator.
+ * This algorithm is not used directly by via StdMeshers_Regular_1D
+ */
+class StdMeshers_AdaptiveAlgo_1D : public StdMeshers_Regular_1D
+{
+public:
+
+  StdMeshers_AdaptiveAlgo_1D(int hypId, int studyId, SMESH_Gen* gen);
+
+  void SetHypothesis( const StdMeshers_Adaptive1D* hyp );
+
+  bool Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
+               double* progress, int* progressTic );
+  virtual bool Evaluate(SMESH_Mesh &         theMesh,
+                        const TopoDS_Shape & theShape,
+                        MapShapeNbElems&     theResMap);
+
+private:
+
+  const StdMeshers_Adaptive1D* myHyp;
+};
+
+#endif
index 303b4794b21a99aa3a2faf90f40739bec492f9a1..cf4120437517a5885616c93e3d1a473df4ea0072 100644 (file)
 //  Module : SMESH
 //
 #include "StdMeshers_Regular_1D.hxx"
 //  Module : SMESH
 //
 #include "StdMeshers_Regular_1D.hxx"
-#include "StdMeshers_Distribution.hxx"
 
 
+#include "SMDS_MeshElement.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "SMESH_Comment.hxx"
+#include "SMESH_Gen.hxx"
+#include "SMESH_HypoFilter.hxx"
+#include "SMESH_Mesh.hxx"
+#include "SMESH_subMesh.hxx"
+#include "SMESH_subMeshEventListener.hxx"
+#include "StdMeshers_Adaptive1D.hxx"
 #include "StdMeshers_Arithmetic1D.hxx"
 #include "StdMeshers_AutomaticLength.hxx"
 #include "StdMeshers_Deflection1D.hxx"
 #include "StdMeshers_Arithmetic1D.hxx"
 #include "StdMeshers_AutomaticLength.hxx"
 #include "StdMeshers_Deflection1D.hxx"
+#include "StdMeshers_Distribution.hxx"
+#include "StdMeshers_FixedPoints1D.hxx"
 #include "StdMeshers_LocalLength.hxx"
 #include "StdMeshers_MaxLength.hxx"
 #include "StdMeshers_NumberOfSegments.hxx"
 #include "StdMeshers_LocalLength.hxx"
 #include "StdMeshers_MaxLength.hxx"
 #include "StdMeshers_NumberOfSegments.hxx"
 #include "StdMeshers_SegmentLengthAroundVertex.hxx"
 #include "StdMeshers_StartEndLength.hxx"
 
 #include "StdMeshers_SegmentLengthAroundVertex.hxx"
 #include "StdMeshers_StartEndLength.hxx"
 
-#include "SMESH_Gen.hxx"
-#include "SMESH_Mesh.hxx"
-#include "SMESH_HypoFilter.hxx"
-#include "SMESH_subMesh.hxx"
-#include "SMESH_subMeshEventListener.hxx"
-#include "SMESH_Comment.hxx"
-
-#include "SMDS_MeshElement.hxx"
-#include "SMDS_MeshNode.hxx"
-
 #include "Utils_SALOME_Exception.hxx"
 #include "utilities.h"
 
 #include "Utils_SALOME_Exception.hxx"
 #include "utilities.h"
 
@@ -75,29 +75,31 @@ using namespace std;
 //=============================================================================
 
 StdMeshers_Regular_1D::StdMeshers_Regular_1D(int hypId, int studyId,
 //=============================================================================
 
 StdMeshers_Regular_1D::StdMeshers_Regular_1D(int hypId, int studyId,
-        SMESH_Gen * gen):SMESH_1D_Algo(hypId, studyId, gen)
+                                             SMESH_Gen * gen)
+  :SMESH_1D_Algo(hypId, studyId, gen)
 {
 {
-        MESSAGE("StdMeshers_Regular_1D::StdMeshers_Regular_1D");
-        _name = "Regular_1D";
-        _shapeType = (1 << TopAbs_EDGE);
-        _fpHyp = 0;
-
-        _compatibleHypothesis.push_back("LocalLength");
-        _compatibleHypothesis.push_back("MaxLength");
-        _compatibleHypothesis.push_back("NumberOfSegments");
-        _compatibleHypothesis.push_back("StartEndLength");
-        _compatibleHypothesis.push_back("Deflection1D");
-        _compatibleHypothesis.push_back("Arithmetic1D");
-        _compatibleHypothesis.push_back("FixedPoints1D");
-        _compatibleHypothesis.push_back("AutomaticLength");
-
-        _compatibleHypothesis.push_back("QuadraticMesh"); // auxiliary !!!
-        _compatibleHypothesis.push_back("Propagation"); // auxiliary !!!
+  MESSAGE("StdMeshers_Regular_1D::StdMeshers_Regular_1D");
+  _name = "Regular_1D";
+  _shapeType = (1 << TopAbs_EDGE);
+  _fpHyp = 0;
+
+  _compatibleHypothesis.push_back("LocalLength");
+  _compatibleHypothesis.push_back("MaxLength");
+  _compatibleHypothesis.push_back("NumberOfSegments");
+  _compatibleHypothesis.push_back("StartEndLength");
+  _compatibleHypothesis.push_back("Deflection1D");
+  _compatibleHypothesis.push_back("Arithmetic1D");
+  _compatibleHypothesis.push_back("FixedPoints1D");
+  _compatibleHypothesis.push_back("AutomaticLength");
+  _compatibleHypothesis.push_back("Adaptive1D");
+
+  _compatibleHypothesis.push_back("QuadraticMesh"); // auxiliary !!!
+  _compatibleHypothesis.push_back("Propagation"); // auxiliary !!!
 }
 
 //=============================================================================
 /*!
 }
 
 //=============================================================================
 /*!
- *  
+ *
  */
 //=============================================================================
 
  */
 //=============================================================================
 
@@ -111,13 +113,13 @@ StdMeshers_Regular_1D::~StdMeshers_Regular_1D()
  */
 //=============================================================================
 
  */
 //=============================================================================
 
-bool StdMeshers_Regular_1D::CheckHypothesis
-                         (SMESH_Mesh&                          aMesh,
-                          const TopoDS_Shape&                  aShape,
-                          SMESH_Hypothesis::Hypothesis_Status& aStatus)
+bool StdMeshers_Regular_1D::CheckHypothesis( SMESH_Mesh&         aMesh,
+                                             const TopoDS_Shape& aShape,
+                                             Hypothesis_Status&  aStatus )
 {
   _hypType = NONE;
   _quadraticMesh = false;
 {
   _hypType = NONE;
   _quadraticMesh = false;
+  _onlyUnaryInput = true;
 
   const list <const SMESHDS_Hypothesis * > & hyps =
     GetUsedHypothesis(aMesh, aShape, /*ignoreAuxiliaryHyps=*/false);
 
   const list <const SMESHDS_Hypothesis * > & hyps =
     GetUsedHypothesis(aMesh, aShape, /*ignoreAuxiliaryHyps=*/false);
@@ -263,12 +265,17 @@ bool StdMeshers_Regular_1D::CheckHypothesis
       (dynamic_cast <const StdMeshers_AutomaticLength * >(theHyp));
     ASSERT(hyp);
     _value[ BEG_LENGTH_IND ] = _value[ END_LENGTH_IND ] = hyp->GetLength( &aMesh, aShape );
       (dynamic_cast <const StdMeshers_AutomaticLength * >(theHyp));
     ASSERT(hyp);
     _value[ BEG_LENGTH_IND ] = _value[ END_LENGTH_IND ] = hyp->GetLength( &aMesh, aShape );
-//     _value[ BEG_LENGTH_IND ] = hyp->GetLength( &aMesh, aShape );
-//     _value[ END_LENGTH_IND ] = Precision::Confusion(); // ?? or set to zero?
     ASSERT( _value[ BEG_LENGTH_IND ] > 0 );
     _hypType = MAX_LENGTH;
     aStatus = SMESH_Hypothesis::HYP_OK;
   }
     ASSERT( _value[ BEG_LENGTH_IND ] > 0 );
     _hypType = MAX_LENGTH;
     aStatus = SMESH_Hypothesis::HYP_OK;
   }
+  else if (hypName == "Adaptive1D")
+  {
+    _adaptiveHyp = dynamic_cast < const StdMeshers_Adaptive1D* >(theHyp);
+    ASSERT(_adaptiveHyp);
+    _hypType = ADAPTIVE;
+    _onlyUnaryInput = false;
+  }
   else
     aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
 
   else
     aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
 
@@ -950,6 +957,13 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t
   if ( _hypType == NONE )
     return false;
 
   if ( _hypType == NONE )
     return false;
 
+  if ( _hypType == ADAPTIVE )
+  {
+    _adaptiveHyp->GetAlgo()->InitComputeError();
+    _adaptiveHyp->GetAlgo()->Compute( theMesh, theShape, &_progress, &_progressTic );
+    return error( _adaptiveHyp->GetAlgo()->GetComputeError() );
+  }
+
   SMESHDS_Mesh * meshDS = theMesh.GetMeshDS();
 
   const TopoDS_Edge & EE = TopoDS::Edge(theShape);
   SMESHDS_Mesh * meshDS = theMesh.GetMeshDS();
 
   const TopoDS_Edge & EE = TopoDS::Edge(theShape);
@@ -1128,11 +1142,15 @@ bool StdMeshers_Regular_1D::Evaluate(SMESH_Mesh & theMesh,
   if ( _hypType == NONE )
     return false;
 
   if ( _hypType == NONE )
     return false;
 
-  //SMESHDS_Mesh * meshDS = theMesh.GetMeshDS();
+  if ( _hypType == ADAPTIVE )
+  {
+    _adaptiveHyp->GetAlgo()->InitComputeError();
+    _adaptiveHyp->GetAlgo()->Evaluate( theMesh, theShape, aResMap );
+    return error( _adaptiveHyp->GetAlgo()->GetComputeError() );
+  }
 
   const TopoDS_Edge & EE = TopoDS::Edge(theShape);
   TopoDS_Edge E = TopoDS::Edge(EE.Oriented(TopAbs_FORWARD));
 
   const TopoDS_Edge & EE = TopoDS::Edge(theShape);
   TopoDS_Edge E = TopoDS::Edge(EE.Oriented(TopAbs_FORWARD));
-  //  int shapeID = meshDS->ShapeToIndex( E );
 
   double f, l;
   Handle(Geom_Curve) Curve = BRep_Tool::Curve(E, f, l);
 
   double f, l;
   Handle(Geom_Curve) Curve = BRep_Tool::Curve(E, f, l);
@@ -1237,3 +1255,16 @@ StdMeshers_Regular_1D::GetUsedHypothesis(SMESH_Mesh &         aMesh,
 
   return _usedHypList;
 }
 
   return _usedHypList;
 }
+
+//================================================================================
+/*!
+ * \brief Pass CancelCompute() to a child algorithm
+ */
+//================================================================================
+
+void StdMeshers_Regular_1D::CancelCompute()
+{
+  SMESH_Algo::CancelCompute();
+  if ( _hypType == ADAPTIVE )
+    _adaptiveHyp->GetAlgo()->CancelCompute();
+}
index e536aa3d97d3386f1475f3de89b5b4f44bcfb949..1551affd69c149a6b098a740758aa607bcad01c8 100644 (file)
 
 #include "SMESH_Algo.hxx"
 
 
 #include "SMESH_Algo.hxx"
 
-#include "StdMeshers_FixedPoints1D.hxx"
-
 class Adaptor3d_Curve;
 class Adaptor3d_Curve;
-class TopoDS_Vertex;
+class StdMeshers_Adaptive1D;
+class StdMeshers_AdaptiveAlgo_1D;
+class StdMeshers_FixedPoints1D;
 class StdMeshers_SegmentLengthAroundVertex;
 class StdMeshers_SegmentLengthAroundVertex;
+class TopoDS_Vertex;
 
 class STDMESHERS_EXPORT StdMeshers_Regular_1D: public SMESH_1D_Algo
 {
 
 class STDMESHERS_EXPORT StdMeshers_Regular_1D: public SMESH_1D_Algo
 {
@@ -55,6 +56,8 @@ public:
   virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
                         MapShapeNbElems& aResMap);
 
   virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape,
                         MapShapeNbElems& aResMap);
 
+  virtual void CancelCompute();
+
   virtual const std::list <const SMESHDS_Hypothesis *> &
     GetUsedHypothesis(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, const bool=true);
 
   virtual const std::list <const SMESHDS_Hypothesis *> &
     GetUsedHypothesis(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, const bool=true);
 
@@ -100,7 +103,7 @@ protected:
   StdMeshers_SegmentLengthAroundVertex* getVertexHyp(SMESH_Mesh &          theMesh,
                                                      const TopoDS_Vertex & theV);
 
   StdMeshers_SegmentLengthAroundVertex* getVertexHyp(SMESH_Mesh &          theMesh,
                                                      const TopoDS_Vertex & theV);
 
-  enum HypothesisType { LOCAL_LENGTH, MAX_LENGTH, NB_SEGMENTS, BEG_END_LENGTH, DEFLECTION, ARITHMETIC_1D, FIXED_POINTS_1D, NONE };
+  enum HypothesisType { LOCAL_LENGTH, MAX_LENGTH, NB_SEGMENTS, BEG_END_LENGTH, DEFLECTION, ARITHMETIC_1D, FIXED_POINTS_1D, ADAPTIVE, NONE };
 
   enum ValueIndex {
     SCALE_FACTOR_IND = 0,
 
   enum ValueIndex {
     SCALE_FACTOR_IND = 0,
@@ -111,9 +114,9 @@ protected:
   };
 
   enum IValueIndex {
   };
 
   enum IValueIndex {
-    NB_SEGMENTS_IND  = 0,
-    DISTR_TYPE_IND   = 1,
-    CONV_MODE_IND    = 2
+    NB_SEGMENTS_IND   = 0,
+    DISTR_TYPE_IND    = 1,
+    CONV_MODE_IND     = 2
   };
 
   enum VValueIndex {
   };
 
   enum VValueIndex {
@@ -127,6 +130,8 @@ protected:
   HypothesisType _hypType;
 
   const StdMeshers_FixedPoints1D* _fpHyp;
   HypothesisType _hypType;
 
   const StdMeshers_FixedPoints1D* _fpHyp;
+  const StdMeshers_Adaptive1D*    _adaptiveHyp;
+  StdMeshers_AdaptiveAlgo_1D*     getAdaptiveAlgo();
 
   double _value[2];
   int    _ivalue[3];
 
   double _value[2];
   int    _ivalue[3];
index 493235b15b59aa1633bf0f0a62217d3f4964dd74..ca774d105c118f684ab2517e567f0bf1952146a1 100644 (file)
@@ -582,6 +582,17 @@ QString StdMeshersGUI_StdHypothesisCreator::storeParams() const
       h->SetVarParameter( params[0].text(), "SetDeflection" );
       h->SetDeflection( params[0].myValue.toDouble() );
     }
       h->SetVarParameter( params[0].text(), "SetDeflection" );
       h->SetDeflection( params[0].myValue.toDouble() );
     }
+    else if( hypType()=="Adaptive1D" )
+    {
+      StdMeshers::StdMeshers_Adaptive1D_var h =
+        StdMeshers::StdMeshers_Adaptive1D::_narrow( hypothesis() );
+      h->SetVarParameter( params[0].text(), "SetMinSize" );
+      h->SetMinSize( params[0].myValue.toDouble() );
+      h->SetVarParameter( params[0].text(), "SetMaxSize" );
+      h->SetMaxSize( params[1].myValue.toDouble() );
+      h->SetVarParameter( params[0].text(), "SetDeflection" );
+      h->SetDeflection( params[2].myValue.toDouble() );
+    }
     else if( hypType()=="AutomaticLength" )
     {
       StdMeshers::StdMeshers_AutomaticLength_var h =
     else if( hypType()=="AutomaticLength" )
     {
       StdMeshers::StdMeshers_AutomaticLength_var h =
@@ -960,7 +971,27 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const
   {
     StdMeshers::StdMeshers_Deflection1D_var h =
       StdMeshers::StdMeshers_Deflection1D::_narrow( hyp );
   {
     StdMeshers::StdMeshers_Deflection1D_var h =
       StdMeshers::StdMeshers_Deflection1D::_narrow( hyp );
-    
+
+    item.myName = tr( "SMESH_DEFLECTION1D_PARAM" );
+    if(!initVariableName( hyp, item, "SetDeflection" )) 
+      item.myValue = h->GetDeflection();
+    p.append( item );
+  }
+  else if( hypType()=="Adaptive1D" )
+  {
+    StdMeshers::StdMeshers_Adaptive1D_var h =
+      StdMeshers::StdMeshers_Adaptive1D::_narrow( hyp );
+
+    item.myName = tr( "SMESH_MIN_SIZE" );
+    if(!initVariableName( hyp, item, "SetMinSize" )) 
+      item.myValue = h->GetMinSize();
+    p.append( item );
+
+    item.myName = tr( "SMESH_MAX_SIZE" );
+    if(!initVariableName( hyp, item, "SetMaxSize" )) 
+      item.myValue = h->GetMaxSize();
+    p.append( item );
+
     item.myName = tr( "SMESH_DEFLECTION1D_PARAM" );
     if(!initVariableName( hyp, item, "SetDeflection" )) 
       item.myValue = h->GetDeflection();
     item.myName = tr( "SMESH_DEFLECTION1D_PARAM" );
     if(!initVariableName( hyp, item, "SetDeflection" )) 
       item.myValue = h->GetDeflection();
@@ -1315,6 +1346,10 @@ void StdMeshersGUI_StdHypothesisCreator::attuneStdWidget (QWidget* w, const int)
     {
       sb->RangeStepAndValidator( VALUE_SMALL, VALUE_MAX, 1.0, "parametric_precision" );
     }
     {
       sb->RangeStepAndValidator( VALUE_SMALL, VALUE_MAX, 1.0, "parametric_precision" );
     }
+    else if( hypType()=="Adaptive1D" )
+    {
+      sb->RangeStepAndValidator( VALUE_SMALL, VALUE_MAX, 1.0, "length_precision" );
+    }
     else if( hypType().startsWith( "ViscousLayers" ))
     {
       if (sb->objectName() == tr("SMESH_STRETCH_FACTOR"))
     else if( hypType().startsWith( "ViscousLayers" ))
     {
       if (sb->objectName() == tr("SMESH_STRETCH_FACTOR"))
@@ -1386,6 +1421,7 @@ QString StdMeshersGUI_StdHypothesisCreator::hypTypeName( const QString& t ) cons
     types.insert( "MaxElementVolume", "MAX_ELEMENT_VOLUME" );
     types.insert( "StartEndLength", "START_END_LENGTH" );
     types.insert( "Deflection1D", "DEFLECTION1D" );
     types.insert( "MaxElementVolume", "MAX_ELEMENT_VOLUME" );
     types.insert( "StartEndLength", "START_END_LENGTH" );
     types.insert( "Deflection1D", "DEFLECTION1D" );
+    types.insert( "Adaptive1D", "ADAPTIVE1D" );
     types.insert( "Arithmetic1D", "ARITHMETIC_1D" );
     types.insert( "FixedPoints1D", "FIXED_POINTS_1D" );
     types.insert( "AutomaticLength", "AUTOMATIC_LENGTH" );
     types.insert( "Arithmetic1D", "ARITHMETIC_1D" );
     types.insert( "FixedPoints1D", "FIXED_POINTS_1D" );
     types.insert( "AutomaticLength", "AUTOMATIC_LENGTH" );
index aaf16607c11a5eae684e9f32c22a4933111ee626..a729340e2902e8852c3f8effc7ff6f85b1b39c87 100644 (file)
             <source>ICON_DLG_DEFLECTION1D</source>
             <translation>mesh_hypo_length.png</translation>
         </message>
             <source>ICON_DLG_DEFLECTION1D</source>
             <translation>mesh_hypo_length.png</translation>
         </message>
+        <message>
+            <source>ICON_DLG_ADAPTIVE1D</source>
+            <translation>mesh_hypo_length.png</translation>
+        </message>
         <message>
             <source>ICON_DLG_GEOMETRIC_1D</source>
             <translation>mesh_hypo_length.png</translation>
         <message>
             <source>ICON_DLG_GEOMETRIC_1D</source>
             <translation>mesh_hypo_length.png</translation>
             <source>ICON_SMESH_TREE_HYPO_Deflection1D</source>
             <translation>mesh_tree_hypo_length.png</translation>
         </message>
             <source>ICON_SMESH_TREE_HYPO_Deflection1D</source>
             <translation>mesh_tree_hypo_length.png</translation>
         </message>
+        <message>
+            <source>ICON_SMESH_TREE_HYPO_Adaptive1D</source>
+            <translation>mesh_tree_hypo_length.png</translation>
+        </message>
         <message>
             <source>ICON_SMESH_TREE_HYPO_LayerDistribution</source>
             <translation>mesh_tree_hypo_layers_distribution.png</translation>
         <message>
             <source>ICON_SMESH_TREE_HYPO_LayerDistribution</source>
             <translation>mesh_tree_hypo_layers_distribution.png</translation>
index cfc5d535dd2343f442cf72ad438e04eda06251c4..c9982405eed93452836a1e3f84f8bc1fee9b19c1 100644 (file)
         <source>SMESH_CUT_NEG_MODE</source>
         <translation>Cut negative</translation>
     </message>
         <source>SMESH_CUT_NEG_MODE</source>
         <translation>Cut negative</translation>
     </message>
+    <message>
+        <source>SMESH_ADAPTIVE1D_HYPOTHESIS</source>
+        <translation>Adaptive</translation>
+    </message>
+    <message>
+        <source>SMESH_MIN_SIZE</source>
+        <translation>Min size</translation>
+    </message>
+    <message>
+        <source>SMESH_MAX_SIZE</source>
+        <translation>Max size</translation>
+    </message>
+    <message>
+        <source>SMESH_ADAPTIVE1D_TITLE</source>
+        <translation>Hypothesis Construction</translation>
+    </message>
     <message>
         <source>SMESH_DEFLECTION1D_HYPOTHESIS</source>
         <translation>Deflection 1D</translation>
     <message>
         <source>SMESH_DEFLECTION1D_HYPOTHESIS</source>
         <translation>Deflection 1D</translation>
index be2903f916235c82798f1df30befff7078c341e3..51cbd0c0d14ce1b14409fb8cb0606e457e42d8fc 100644 (file)
@@ -170,6 +170,7 @@ SET(StdMeshersEngine_SOURCES
   StdMeshers_ViscousLayers2D_i.cxx
   StdMeshers_CartesianParameters3D_i.cxx
   StdMeshers_Cartesian_3D_i.cxx
   StdMeshers_ViscousLayers2D_i.cxx
   StdMeshers_CartesianParameters3D_i.cxx
   StdMeshers_Cartesian_3D_i.cxx
+  StdMeshers_Adaptive1D_i.cxx 
 )
 
 IF(SALOME_SMESH_ENABLE_MEFISTO)
 )
 
 IF(SALOME_SMESH_ENABLE_MEFISTO)
diff --git a/src/StdMeshers_I/StdMeshers_Adaptive1D_i.cxx b/src/StdMeshers_I/StdMeshers_Adaptive1D_i.cxx
new file mode 100644 (file)
index 0000000..99bc768
--- /dev/null
@@ -0,0 +1,173 @@
+// Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//  File   : StdMeshers_Adaptive1D_i.cxx
+//  Module : SMESH
+//
+
+#include "StdMeshers_Adaptive1D_i.hxx"
+#include "SMESH_Gen_i.hxx"
+#include "SMESH_Gen.hxx"
+#include "SMESH_PythonDump.hxx"
+
+#include "StdMeshers_Adaptive1D.hxx"
+
+#include "Utils_CorbaException.hxx"
+#include "utilities.h"
+
+//=======================================================================
+//function : StdMeshers_Adaptive1D_i
+//purpose  : Constructor
+//=======================================================================
+
+StdMeshers_Adaptive1D_i::StdMeshers_Adaptive1D_i( PortableServer::POA_ptr thePOA,
+                                                  int                     theStudyId,
+                                                  ::SMESH_Gen*            theGenImpl )
+  : SALOME::GenericObj_i( thePOA ), 
+    SMESH_Hypothesis_i( thePOA )
+{
+  myBaseImpl = new ::StdMeshers_Adaptive1D( theGenImpl->GetANewId(),
+                                            theStudyId,
+                                            theGenImpl );
+}
+
+//=======================================================================
+//function : ~StdMeshers_Adaptive1D_i
+//purpose  : Destructor
+//=======================================================================
+
+StdMeshers_Adaptive1D_i::~StdMeshers_Adaptive1D_i()
+{
+  MESSAGE( "StdMeshers_Adaptive1D_i::~StdMeshers_Adaptive1D_i" );
+}
+
+//=======================================================================
+//function : SetMinSize
+//purpose  : Sets minimal allowed segment length
+//=======================================================================
+
+void StdMeshers_Adaptive1D_i::SetMinSize( CORBA::Double minSegLen )
+  throw (SALOME::SALOME_Exception)
+{
+  ASSERT( myBaseImpl );
+  try {
+    this->GetImpl()->SetMinSize( minSegLen );
+  }
+  catch ( SALOME_Exception& S_ex ) {
+    THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM );
+  }
+
+  // Update Python script
+  SMESH::TPythonDump() << _this() << ".SetMinSize( " << SMESH::TVar(minSegLen) << " )";
+}
+
+//=======================================================================
+//function : GetMinSize
+//purpose  : Returns minimal allowed segment length
+//=======================================================================
+
+CORBA::Double StdMeshers_Adaptive1D_i::GetMinSize()
+{
+  ASSERT( myBaseImpl );
+  return this->GetImpl()->GetMinSize();
+}
+
+//=======================================================================
+//function : SetMaxSize
+//purpose  : Sets maximal allowed segment length
+//=======================================================================
+
+void StdMeshers_Adaptive1D_i::SetMaxSize( CORBA::Double maxSegLen )
+  throw (SALOME::SALOME_Exception)
+{
+  ASSERT( myBaseImpl );
+  try {
+    this->GetImpl()->SetMaxSize( maxSegLen );
+  }
+  catch ( SALOME_Exception& S_ex ) {
+    THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM );
+  }
+
+  // Update Python script
+  SMESH::TPythonDump() << _this() << ".SetMaxSize( " << SMESH::TVar(maxSegLen) << " )";
+}
+
+//=======================================================================
+//function : GetMaxSize
+//purpose  : Returns maximal allowed segment length
+//=======================================================================
+
+CORBA::Double StdMeshers_Adaptive1D_i::GetMaxSize()
+{
+  ASSERT( myBaseImpl );
+  return this->GetImpl()->GetMaxSize();
+}
+
+//=======================================================================
+//function : SetDeflection
+//purpose  : Sets a maximal allowed distance between a segment and an edge.
+//=======================================================================
+
+void StdMeshers_Adaptive1D_i::SetDeflection( CORBA::Double theValue )
+  throw ( SALOME::SALOME_Exception )
+{
+  ASSERT( myBaseImpl );
+  try {
+    this->GetImpl()->SetDeflection( theValue );
+  }
+  catch ( SALOME_Exception& S_ex ) {
+    THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM );
+  }
+
+  // Update Python script
+  SMESH::TPythonDump() << _this() << ".SetDeflection( " << SMESH::TVar(theValue) << " )";
+}
+
+//=======================================================================
+//function : GetDeflection
+//purpose  : Returns deflection
+//=======================================================================
+
+CORBA::Double StdMeshers_Adaptive1D_i::GetDeflection()
+{
+  ASSERT( myBaseImpl );
+  return this->GetImpl()->GetDeflection();
+}
+
+//=======================================================================
+//function : GetImpl
+//purpose  : Get implementation
+//=======================================================================
+
+::StdMeshers_Adaptive1D* StdMeshers_Adaptive1D_i::GetImpl()
+{
+  return ( ::StdMeshers_Adaptive1D* )myBaseImpl;
+}
+
+//=======================================================================
+//function : IsDimSupported
+//purpose  : Verify whether hypothesis supports given entity type
+//=======================================================================
+
+CORBA::Boolean StdMeshers_Adaptive1D_i::IsDimSupported( SMESH::Dimension type )
+{
+  return type == SMESH::DIM_1D;
+}
diff --git a/src/StdMeshers_I/StdMeshers_Adaptive1D_i.hxx b/src/StdMeshers_I/StdMeshers_Adaptive1D_i.hxx
new file mode 100644 (file)
index 0000000..ac168ec
--- /dev/null
@@ -0,0 +1,89 @@
+// Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//  File   : StdMeshers_Adaptive1D_i.hxx
+//  Module : SMESH
+//
+#ifndef _SMESH_Adaptive1D_I_HXX_
+#define _SMESH_Adaptive1D_I_HXX_
+
+#include "SMESH_StdMeshers_I.hxx"
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESH_Hypothesis_i.hxx"
+
+class StdMeshers_Adaptive1D;
+class SMESH_Gen;
+
+// ======================================================
+// Adaptive1D hypothesis
+// ======================================================
+
+class STDMESHERS_I_EXPORT StdMeshers_Adaptive1D_i:
+  public virtual POA_StdMeshers::StdMeshers_Adaptive1D,
+  public virtual SMESH_Hypothesis_i
+{
+ public:
+  // Constructor
+  StdMeshers_Adaptive1D_i( PortableServer::POA_ptr thePOA,
+                           int                     theStudyId,
+                           ::SMESH_Gen*            theGenImpl );
+  // Destructor
+  virtual ~StdMeshers_Adaptive1D_i();
+
+  /*!
+   * Sets minimal allowed segment length
+   */
+  void SetMinSize( CORBA::Double minSegLen ) throw (SALOME::SALOME_Exception);
+  CORBA::Double GetMinSize();
+
+  /*!
+   * Sets maximal allowed segment length
+   */
+  void SetMaxSize( CORBA::Double maxSegLen ) throw (SALOME::SALOME_Exception);
+  CORBA::Double GetMaxSize();
+
+  /*!
+   * Sets <deflection> parameter value, 
+   * i.e. a maximal allowed distance between a segment and an edge.
+   */
+  void SetDeflection( CORBA::Double theLength ) throw (SALOME::SALOME_Exception);
+  CORBA::Double GetDeflection();
+
+
+  /*!
+   * Returns implementation
+   */
+  ::StdMeshers_Adaptive1D* GetImpl();
+
+  /*!
+   * \brief Verify whether hypothesis supports given entity type 
+   * \param type - dimension (see SMESH::Dimension enumeration)
+   * \retval CORBA::Boolean - TRUE if dimension is supported, FALSE otherwise
+   *
+   * Verify whether hypothesis supports given entity type (see SMESH::Dimension enumeration)
+   */
+  CORBA::Boolean IsDimSupported( SMESH::Dimension type );
+};
+
+#endif
index a1325710726dd78ff6d7def8fbba80c7531b2993..3cc3ac0507f6d5c96828e1ffecb2753354937aec 100644 (file)
@@ -38,6 +38,7 @@
 #include "StdMeshers_FixedPoints1D_i.hxx"
 #include "StdMeshers_NumberOfSegments_i.hxx"
 #include "StdMeshers_Deflection1D_i.hxx"
 #include "StdMeshers_FixedPoints1D_i.hxx"
 #include "StdMeshers_NumberOfSegments_i.hxx"
 #include "StdMeshers_Deflection1D_i.hxx"
+#include "StdMeshers_Adaptive1D_i.hxx"
 #include "StdMeshers_Propagation_i.hxx"
 #include "StdMeshers_LengthFromEdges_i.hxx"
 #include "StdMeshers_QuadranglePreference_i.hxx"
 #include "StdMeshers_Propagation_i.hxx"
 #include "StdMeshers_LengthFromEdges_i.hxx"
 #include "StdMeshers_QuadranglePreference_i.hxx"
@@ -143,6 +144,8 @@ STDMESHERS_I_EXPORT
       aCreator = new StdHypothesisCreator_i<StdMeshers_StartEndLength_i>;
     else if (strcmp(aHypName, "Deflection1D") == 0)
       aCreator = new StdHypothesisCreator_i<StdMeshers_Deflection1D_i>;
       aCreator = new StdHypothesisCreator_i<StdMeshers_StartEndLength_i>;
     else if (strcmp(aHypName, "Deflection1D") == 0)
       aCreator = new StdHypothesisCreator_i<StdMeshers_Deflection1D_i>;
+    else if (strcmp(aHypName, "Adaptive1D") == 0)
+      aCreator = new StdHypothesisCreator_i<StdMeshers_Adaptive1D_i>;
     else if (strcmp(aHypName, "FixedPoints1D") == 0)
       aCreator = new StdHypothesisCreator_i<StdMeshers_FixedPoints1D_i>;
     else if (strcmp(aHypName, "Arithmetic1D") == 0)
     else if (strcmp(aHypName, "FixedPoints1D") == 0)
       aCreator = new StdHypothesisCreator_i<StdMeshers_FixedPoints1D_i>;
     else if (strcmp(aHypName, "Arithmetic1D") == 0)