Salome HOME
23179: EDF 11603 - Problem with extrusion when path is not well oriented
authoreap <eap@opencascade.com>
Fri, 9 Oct 2015 14:47:17 +0000 (17:47 +0300)
committereap <eap@opencascade.com>
Fri, 9 Oct 2015 14:47:17 +0000 (17:47 +0300)
HYDRO module: Feature #523: river, channel, embankment meshing

12 files changed:
doc/salome/gui/SMESH/images/quad_from_ma_mesh.png
doc/salome/gui/SMESH/input/constructing_meshes.doc
doc/salome/gui/SMESH/input/quad_from_ma_algo.doc
src/SMESH/SMESH_Gen.cxx
src/SMESH/SMESH_MeshEditor.cxx
src/SMESHUtils/SMESH_MAT2d.cxx
src/SMESH_I/SMESH_Group_i.cxx
src/SMESH_I/SMESH_MeshEditor_i.cxx
src/SMESH_SWIG/StdMeshersBuilder.py
src/SMESH_SWIG/smeshBuilder.py
src/SMESH_SWIG/smesh_algorithm.py
src/StdMeshers/StdMeshers_QuadFromMedialAxis_1D2D.cxx

index f233cc640783dea9f48b8889bf27a8d5e9920fc7..3e3c63b23bd8d64dddc806f68f5bb70b7a974ffc 100644 (file)
Binary files a/doc/salome/gui/SMESH/images/quad_from_ma_mesh.png and b/doc/salome/gui/SMESH/images/quad_from_ma_mesh.png differ
index 9e5e639be627f8f8ef580fc5355cdbe948e2f9ac..2ec8a49878fa121577843d32121c0b28324a3421 100644 (file)
@@ -229,6 +229,9 @@ have been defined will be discretized.
     </hypotheses-set-group>
     </meshers>
 ~~~~~~
     </hypotheses-set-group>
     </meshers>
 ~~~~~~
+    If the file contents are incorrect, there can be an error at
+    activation of Mesh module: <em>"fatal parsing error: error
+    triggered by consumer in line ..."</em>
 <br>
 <center>
       \image html hypo_sets.png
 <br>
 <center>
       \image html hypo_sets.png
index 89a919ef349711dda921263d8603595fc3406409..6a90f376e4e63b7de1e9bba8c631fbf7815c1c2a 100644 (file)
@@ -5,13 +5,18 @@
 Medial Axis Projection algorithm can be used for meshing faces with
 sinuous borders and having channel-like shape, for which is it
 difficult to define 1D hypotheses so that generated quadrangles to be
 Medial Axis Projection algorithm can be used for meshing faces with
 sinuous borders and having channel-like shape, for which is it
 difficult to define 1D hypotheses so that generated quadrangles to be
-of good shape.
+of good shape. The algorithm can be also applied to faces with ring
+topology, which can be viewed as a closed 'channel'. In the latter
+case radial discretization of a ring can be specified by
+using <em>Number of Layers</em> or <em>Distribution of Layers</em>
+hypothesis.
 
 
-\image html quad_from_ma_mesh.png "A mesh of a river model"
+\image html quad_from_ma_mesh.png "A mesh of a river model to the left and of a ring-face to the right"
 
 The algorithm assures good shape of quadrangles by constructing Medial
 Axis between sinuous borders of the face and using it to
 
 The algorithm assures good shape of quadrangles by constructing Medial
 Axis between sinuous borders of the face and using it to
-discretize the borders.
+discretize the borders. (Shape of quadrangles can be not perfect at
+locations where opposite sides of a 'channel' are far from being parallel.)
 
 \image html quad_from_ma_medial_axis.png "Medial Axis between two blue sinuous borders"
 
 
 \image html quad_from_ma_medial_axis.png "Medial Axis between two blue sinuous borders"
 
index 037acb584ed255d6d24f85c75aba670be8cd76c6..4c264d50ae52a996e94983c8c87188d0ba7df108 100644 (file)
@@ -441,7 +441,8 @@ void SMESH_Gen::setCurrentSubMesh(SMESH_subMesh* sm)
 {
   if ( sm )
     _sm_current.push_back( sm );
 {
   if ( sm )
     _sm_current.push_back( sm );
-  else
+
+  else if ( !_sm_current.empty() )
     _sm_current.pop_back();
 }
 
     _sm_current.pop_back();
 }
 
index 9cc4d2378405173a2a3360dcedcb04904bf6e047..2c2fc35e0625002af51119b0a739747ff49b1fdb 100644 (file)
@@ -5986,6 +5986,10 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet     theElements[2],
   ASSERT( theTrack );
 
   SMESHDS_SubMesh* pSubMeshDS = theTrack->GetSubMeshDS();
   ASSERT( theTrack );
 
   SMESHDS_SubMesh* pSubMeshDS = theTrack->GetSubMeshDS();
+  if ( !pSubMeshDS )
+    return ExtrusionAlongTrack( theElements, theTrack->GetFather(), theN1,
+                                theHasAngles, theAngles, theLinearVariation,
+                                theHasRefPoint, theRefPoint, theMakeGroups );
 
   aItE = pSubMeshDS->GetElements();
   while ( aItE->more() ) {
 
   aItE = pSubMeshDS->GetElements();
   while ( aItE->more() ) {
index d423f8be89998102df25558d8bbc1a54bf261f8c..970d560e5f0a6d83097bf161c38e6f7c585c6b61 100644 (file)
@@ -344,6 +344,9 @@ namespace
       if ( !_edge || !seg2._edge )
         return true;
 
       if ( !_edge || !seg2._edge )
         return true;
 
+      if ( _edge->twin() == seg2._edge )
+        return true;
+
       const TVDCell* cell1 = this->_edge->twin()->cell();
       const TVDCell* cell2 = seg2. _edge->twin()->cell();
       if ( cell1 == cell2 )
       const TVDCell* cell1 = this->_edge->twin()->cell();
       const TVDCell* cell2 = seg2. _edge->twin()->cell();
       if ( cell1 == cell2 )
@@ -367,8 +370,8 @@ namespace
       else if ( edgeMedium1->is_primary() && edgeMedium2->is_primary() )
       {
         if ( edgeMedium1->twin() == edgeMedium2 &&
       else if ( edgeMedium1->is_primary() && edgeMedium2->is_primary() )
       {
         if ( edgeMedium1->twin() == edgeMedium2 &&
-             SMESH_MAT2d::Branch::getBndSegment( edgeMedium1 ) ==
-             SMESH_MAT2d::Branch::getBndSegment( edgeMedium2 ))
+             SMESH_MAT2d::Branch::getGeomEdge( edgeMedium1 ) ==
+             SMESH_MAT2d::Branch::getGeomEdge( edgeMedium2 ))
           // this is an ignored MA edge between inSegment's on one EDGE forming a convex corner
           return true;
       }
           // this is an ignored MA edge between inSegment's on one EDGE forming a convex corner
           return true;
       }
@@ -413,7 +416,7 @@ namespace
    */
   //================================================================================
 
    */
   //================================================================================
 
-  void bndSegsToMesh( const vector< BndSeg >& bndSegs )
+  void bndSegsToMesh( const vector< vector< BndSeg > >& bndSegsPerEdge )
   {
 #ifdef _MYDEBUG_
     if ( !getenv("bndSegsToMesh")) return;
   {
 #ifdef _MYDEBUG_
     if ( !getenv("bndSegsToMesh")) return;
@@ -431,31 +434,35 @@ namespace
     text << "from salome.smesh import smeshBuilder\n";
     text << "smesh = smeshBuilder.New(salome.myStudy)\n";
     text << "m=smesh.Mesh()\n";
     text << "from salome.smesh import smeshBuilder\n";
     text << "smesh = smeshBuilder.New(salome.myStudy)\n";
     text << "m=smesh.Mesh()\n";
-    for ( size_t i = 0; i < bndSegs.size(); ++i )
+    for ( size_t iE = 0; iE < bndSegsPerEdge.size(); ++iE )
     {
     {
-      if ( !bndSegs[i]._edge )
-        text << "# " << i << " NULL edge\n";
-      else if ( !bndSegs[i]._edge->vertex0() ||
-                !bndSegs[i]._edge->vertex1() )
-        text << "# " << i << " INFINITE edge\n";
-      else if ( addedEdges.insert( bndSegs[i]._edge ).second &&
-                addedEdges.insert( bndSegs[i]._edge->twin() ).second )
+      const vector< BndSeg >& bndSegs = bndSegsPerEdge[ iE ];
+      for ( size_t i = 0; i < bndSegs.size(); ++i )
       {
       {
-        v2n = v2Node.insert( make_pair( bndSegs[i]._edge->vertex0(), v2Node.size() + 1 )).first;
-        int n0 = v2n->second;
-        if ( n0 == v2Node.size() )
-          text << "n" << n0 << " = m.AddNode( "
-               << bndSegs[i]._edge->vertex0()->x() / theScale[0] << ", "
-               << bndSegs[i]._edge->vertex0()->y() / theScale[1] << ", 0 )\n";
-
-        v2n = v2Node.insert( make_pair( bndSegs[i]._edge->vertex1(), v2Node.size() + 1 )).first;
-        int n1 = v2n->second;
-        if ( n1 == v2Node.size() )
-          text << "n" << n1 << " = m.AddNode( "
-               << bndSegs[i]._edge->vertex1()->x() / theScale[0] << ", "
-               << bndSegs[i]._edge->vertex1()->y() / theScale[1] << ", 0 )\n";
-
-        text << "e" << i << " = m.AddEdge([ n" << n0 << ", n" << n1 << " ])\n";
+        if ( !bndSegs[i]._edge )
+          text << "# E=" << iE << " i=" << i << " NULL edge\n";
+        else if ( !bndSegs[i]._edge->vertex0() ||
+                  !bndSegs[i]._edge->vertex1() )
+          text << "# E=" << iE << " i=" << i << " INFINITE edge\n";
+        else if ( addedEdges.insert( bndSegs[i]._edge ).second &&
+                  addedEdges.insert( bndSegs[i]._edge->twin() ).second )
+        {
+          v2n = v2Node.insert( make_pair( bndSegs[i]._edge->vertex0(), v2Node.size() + 1 )).first;
+          int n0 = v2n->second;
+          if ( n0 == v2Node.size() )
+            text << "n" << n0 << " = m.AddNode( "
+                 << bndSegs[i]._edge->vertex0()->x() / theScale[0] << ", "
+                 << bndSegs[i]._edge->vertex0()->y() / theScale[1] << ", 0 )\n";
+
+          v2n = v2Node.insert( make_pair( bndSegs[i]._edge->vertex1(), v2Node.size() + 1 )).first;
+          int n1 = v2n->second;
+          if ( n1 == v2Node.size() )
+            text << "n" << n1 << " = m.AddNode( "
+                 << bndSegs[i]._edge->vertex1()->x() / theScale[0] << ", "
+                 << bndSegs[i]._edge->vertex1()->y() / theScale[1] << ", 0 )\n";
+
+          text << "e" << i << " = m.AddEdge([ n" << n0 << ", n" << n1 << " ])\n";
+        }
       }
     }
     text << "\n";
       }
     }
     text << "\n";
@@ -985,7 +992,7 @@ namespace
       bndSegs[0].setIndexToEdge( 0 );
     }
 
       bndSegs[0].setIndexToEdge( 0 );
     }
 
-    //bndSegsToMesh( bndSegsPerEdge ); // debug: visually check found MA edges
+    bndSegsToMesh( bndSegsPerEdge ); // debug: visually check found MA edges
 
 
     // Find TVDEdge's of Branches and associate them with bndSegs
 
 
     // Find TVDEdge's of Branches and associate them with bndSegs
@@ -1374,6 +1381,15 @@ bool SMESH_MAT2d::Boundary::getBranchPoint( const std::size_t iEdge,
     while ( points._params[i+1] < u ) ++i;
   }
 
     while ( points._params[i+1] < u ) ++i;
   }
 
+  if ( points._params[i] == points._params[i+1] ) // coincident points at some end
+  {
+    int di = ( points._params[0] == points._params[i] ) ? +1 : -1;
+    while ( points._params[i] == points._params[i+1] )
+      i += di;
+    if ( i < 0 || i+1 >= points._params.size() )
+      i = 0;
+  }
+
   double edgeParam = ( u - points._params[i] ) / ( points._params[i+1] - points._params[i] );
 
   if ( !points._maEdges[ i ].second ) // no branch at the EDGE end, look for a closest branch
   double edgeParam = ( u - points._params[i] ) / ( points._params[i+1] - points._params[i] );
 
   if ( !points._maEdges[ i ].second ) // no branch at the EDGE end, look for a closest branch
index 6218de9f8ba5485d3cd07b398da23c30a280d9bd..d51714ae79a7d94929cba87714c2436f2470fd34 100644 (file)
@@ -947,7 +947,8 @@ std::string SMESH_GroupOnFilter_i::FilterToString() const
     {
       SMESH::Filter::Criterion& crit = criteria[ i ];
 
     {
       SMESH::Filter::Criterion& crit = criteria[ i ];
 
-      if ( SMESH::FunctorType( crit.Type ) == SMESH::FT_BelongToMeshGroup )
+      if ( SMESH::FunctorType( crit.Type ) == SMESH::FT_BelongToMeshGroup &&
+           crit.ThresholdID.in() && crit.ThresholdID.in()[0] )
       {
         CORBA::Object_var obj = SMESH_Gen_i::GetORB()->string_to_object( crit.ThresholdID );
         if ( SMESH_GroupBase_i * g = SMESH::DownCast< SMESH_GroupBase_i*>( obj ))
       {
         CORBA::Object_var obj = SMESH_Gen_i::GetORB()->string_to_object( crit.ThresholdID );
         if ( SMESH_GroupBase_i * g = SMESH::DownCast< SMESH_GroupBase_i*>( obj ))
index 44a1bfdfa29bf94a4d6310356bc434b2136581c7..0b927273c4ada665a02e6ea1013ad3285fcf220a 100644 (file)
@@ -2844,7 +2844,7 @@ SMESH_MeshEditor_i::ExtrusionAlongPathObjects(const SMESH::ListOfIDSources & the
     if ( !aMeshImp ) return aGroups._retn();
     TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
     aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
     if ( !aMeshImp ) return aGroups._retn();
     TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
     aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
-    if ( !aSubMesh || !aSubMesh->GetSubMeshDS() )
+    if ( !aSubMesh /*|| !aSubMesh->GetSubMeshDS()*/ )
       return aGroups._retn();
   }
 
       return aGroups._retn();
   }
 
index ce50a39cbdf6ed4545a60b053c6d74a93cc405f9..98acce5f6d38b3d3943984d5619d1d0ecf475b8b 100644 (file)
@@ -1100,8 +1100,7 @@ class StdMeshersBuilder_Prism3D(Mesh_Algorithm):
 
     pass # end of StdMeshersBuilder_Prism3D class
 
 
     pass # end of StdMeshersBuilder_Prism3D class
 
-## Defines a Prism 3D algorithm, which is either "Extrusion 3D" or "Radial Prism"
-#  depending on geometry
+## Defines a Prism 3D algorithm
 # 
 #  It is created by calling smeshBuilder.Mesh.Prism(geom=0)
 #
 # 
 #  It is created by calling smeshBuilder.Mesh.Prism(geom=0)
 #
@@ -1133,30 +1132,12 @@ class StdMeshersBuilder_RadialPrism3D(StdMeshersBuilder_Prism3D):
         self.nbLayers = None
         return
 
         self.nbLayers = None
         return
 
-## Defines a Radial Quadrangle 1D-2D algorithm
+## Base class for algorithms supporting radial distribution hypotheses
 # 
 # 
-#  It is created by calling smeshBuilder.Mesh.Quadrangle(smeshBuilder.RADIAL_QUAD,geom=0)
-#
-#  @ingroup l2_algos_radialq
-class StdMeshersBuilder_RadialQuadrangle1D2D(Mesh_Algorithm):
-
-    ## name of the dynamic method in smeshBuilder.Mesh class
-    #  @internal
-    meshMethod = "Quadrangle"
-    ## type of algorithm used with helper function in smeshBuilder.Mesh class
-    #  @internal
-    algoType   = RADIAL_QUAD
-    ## doc string of the method
-    #  @internal
-    docHelper  = "Creates quadrangle 1D-2D algorithm for faces having a shape of disk or a disk segment"
+class StdMeshersBuilder_RadialAlgorithm(Mesh_Algorithm):
 
 
-    ## Private constructor.
-    #  @param mesh parent mesh object algorithm is assigned to
-    #  @param geom geometry (shape/sub-shape) algorithm is assigned to;
-    #              if it is @c 0 (default), the algorithm is assigned to the main shape
-    def __init__(self, mesh, geom=0):
+    def __init__(self):
         Mesh_Algorithm.__init__(self)
         Mesh_Algorithm.__init__(self)
-        self.Create(mesh, geom, self.algoType)
 
         self.distribHyp = None #self.Hypothesis("LayerDistribution2D", UseExisting=0)
         self.nbLayers = None
 
         self.distribHyp = None #self.Hypothesis("LayerDistribution2D", UseExisting=0)
         self.nbLayers = None
@@ -1259,12 +1240,42 @@ class StdMeshersBuilder_RadialQuadrangle1D2D(Mesh_Algorithm):
 
     pass # end of StdMeshersBuilder_RadialQuadrangle1D2D class
 
 
     pass # end of StdMeshersBuilder_RadialQuadrangle1D2D class
 
+## Defines a Radial Quadrangle 1D-2D algorithm
+# 
+#  It is created by calling smeshBuilder.Mesh.Quadrangle(smeshBuilder.RADIAL_QUAD,geom=0)
+#
+#  @ingroup l2_algos_radialq
+class StdMeshersBuilder_RadialQuadrangle1D2D(StdMeshersBuilder_RadialAlgorithm):
+
+    ## name of the dynamic method in smeshBuilder.Mesh class
+    #  @internal
+    meshMethod = "Quadrangle"
+    ## type of algorithm used with helper function in smeshBuilder.Mesh class
+    #  @internal
+    algoType   = RADIAL_QUAD
+    ## doc string of the method
+    #  @internal
+    docHelper  = "Creates quadrangle 1D-2D algorithm for faces having a shape of disk or a disk segment"
+
+    ## Private constructor.
+    #  @param mesh parent mesh object algorithm is assigned to
+    #  @param geom geometry (shape/sub-shape) algorithm is assigned to;
+    #              if it is @c 0 (default), the algorithm is assigned to the main shape
+    def __init__(self, mesh, geom=0):
+        StdMeshersBuilder_RadialAlgorithm.__init__(self)
+        self.Create(mesh, geom, self.algoType)
+
+        self.distribHyp = None #self.Hypothesis("LayerDistribution2D", UseExisting=0)
+        self.nbLayers = None
+        pass
+
+
 ## Defines a Quadrangle (Medial Axis Projection) 1D-2D algorithm
 # 
 #  It is created by calling smeshBuilder.Mesh.Quadrangle(smeshBuilder.QUAD_MA_PROJ,geom=0)
 #
 #  @ingroup l2_algos_quad_ma
 ## Defines a Quadrangle (Medial Axis Projection) 1D-2D algorithm
 # 
 #  It is created by calling smeshBuilder.Mesh.Quadrangle(smeshBuilder.QUAD_MA_PROJ,geom=0)
 #
 #  @ingroup l2_algos_quad_ma
-class StdMeshersBuilder_QuadMA_1D2D(Mesh_Algorithm):
+class StdMeshersBuilder_QuadMA_1D2D(StdMeshersBuilder_RadialAlgorithm):
 
     ## name of the dynamic method in smeshBuilder.Mesh class
     #  @internal
 
     ## name of the dynamic method in smeshBuilder.Mesh class
     #  @internal
@@ -1281,7 +1292,7 @@ class StdMeshersBuilder_QuadMA_1D2D(Mesh_Algorithm):
     #  @param geom geometry (shape/sub-shape) algorithm is assigned to;
     #              if it is @c 0 (default), the algorithm is assigned to the main shape
     def __init__(self, mesh, geom=0):
     #  @param geom geometry (shape/sub-shape) algorithm is assigned to;
     #              if it is @c 0 (default), the algorithm is assigned to the main shape
     def __init__(self, mesh, geom=0):
-        Mesh_Algorithm.__init__(self)
+        StdMeshersBuilder_RadialAlgorithm.__init__(self)
         self.Create(mesh, geom, self.algoType)
         pass
 
         self.Create(mesh, geom, self.algoType)
         pass
 
index 8f49d4937cd8d07035f7a8d1bbdd4d2f2e37c5d3..22ea69d836f27507b247dc6893f7b63a9adf056b 100644 (file)
@@ -3987,6 +3987,7 @@ class Mesh:
         if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
             RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
         if isinstance( RefPoint, list ):
         if isinstance( RefPoint, geomBuilder.GEOM._objref_GEOM_Object):
             RefPoint = self.smeshpyD.GetPointStruct(RefPoint)
         if isinstance( RefPoint, list ):
+            if not RefPoint: RefPoint = [0,0,0]
             RefPoint = SMESH.PointStruct( *RefPoint )
         if isinstance( PathMesh, Mesh ):
             PathMesh = PathMesh.GetMesh()
             RefPoint = SMESH.PointStruct( *RefPoint )
         if isinstance( PathMesh, Mesh ):
             PathMesh = PathMesh.GetMesh()
@@ -4019,8 +4020,9 @@ class Mesh:
     #          only SMESH::Extrusion_Error otherwise
     #  @ingroup l2_modif_extrurev
     def ExtrusionAlongPathX(self, Base, Path, NodeStart,
     #          only SMESH::Extrusion_Error otherwise
     #  @ingroup l2_modif_extrurev
     def ExtrusionAlongPathX(self, Base, Path, NodeStart,
-                            HasAngles, Angles, LinearVariation,
-                            HasRefPoint, RefPoint, MakeGroups, ElemType):
+                            HasAngles=False, Angles=[], LinearVariation=False,
+                            HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
+                            ElemType=SMESH.FACE):
         n,e,f = [],[],[]
         if ElemType == SMESH.NODE: n = Base
         if ElemType == SMESH.EDGE: e = Base
         n,e,f = [],[],[]
         if ElemType == SMESH.NODE: n = Base
         if ElemType == SMESH.EDGE: e = Base
@@ -4050,7 +4052,7 @@ class Mesh:
     #          only SMESH::Extrusion_Error otherwise
     #  @ingroup l2_modif_extrurev
     def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
     #          only SMESH::Extrusion_Error otherwise
     #  @ingroup l2_modif_extrurev
     def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
-                           HasAngles, Angles, HasRefPoint, RefPoint,
+                           HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
                            MakeGroups=False, LinearVariation=False):
         n,e,f = [],IDsOfElements,IDsOfElements
         gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
                            MakeGroups=False, LinearVariation=False):
         n,e,f = [],IDsOfElements,IDsOfElements
         gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape,
@@ -4080,7 +4082,7 @@ class Mesh:
     #          only SMESH::Extrusion_Error otherwise
     #  @ingroup l2_modif_extrurev
     def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
     #          only SMESH::Extrusion_Error otherwise
     #  @ingroup l2_modif_extrurev
     def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
-                                 HasAngles, Angles, HasRefPoint, RefPoint,
+                                 HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
                                  MakeGroups=False, LinearVariation=False):
         n,e,f = [],theObject,theObject
         gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
                                  MakeGroups=False, LinearVariation=False):
         n,e,f = [],theObject,theObject
         gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
@@ -4109,7 +4111,7 @@ class Mesh:
     #          only SMESH::Extrusion_Error otherwise
     #  @ingroup l2_modif_extrurev
     def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
     #          only SMESH::Extrusion_Error otherwise
     #  @ingroup l2_modif_extrurev
     def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
-                                   HasAngles, Angles, HasRefPoint, RefPoint,
+                                   HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
                                    MakeGroups=False, LinearVariation=False):
         n,e,f = [],theObject,[]
         gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
                                    MakeGroups=False, LinearVariation=False):
         n,e,f = [],theObject,[]
         gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
@@ -4138,7 +4140,7 @@ class Mesh:
     #          only SMESH::Extrusion_Error otherwise
     #  @ingroup l2_modif_extrurev
     def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
     #          only SMESH::Extrusion_Error otherwise
     #  @ingroup l2_modif_extrurev
     def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
-                                   HasAngles, Angles, HasRefPoint, RefPoint,
+                                   HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
                                    MakeGroups=False, LinearVariation=False):
         n,e,f = [],[],theObject
         gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
                                    MakeGroups=False, LinearVariation=False):
         n,e,f = [],[],theObject
         gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart,
index 9481ff1d743df8a849b48b320e8964176140c751..a57b034633f9e65d9c1a8e809aece3bd0405a79f 100644 (file)
@@ -85,6 +85,7 @@ class Mesh_Algorithm:
                     attr = hypo_so_i.FindAttribute("AttributeIOR")[1]
                     if attr is not None:
                         anIOR = attr.Value()
                     attr = hypo_so_i.FindAttribute("AttributeIOR")[1]
                     if attr is not None:
                         anIOR = attr.Value()
+                        if not anIOR: continue # prevent exception in orb.string_to_object()
                         hypo_o_i = salome.orb.string_to_object(anIOR)
                         if hypo_o_i is not None:
                             # Check if this is a hypothesis
                         hypo_o_i = salome.orb.string_to_object(anIOR)
                         if hypo_o_i is not None:
                             # Check if this is a hypothesis
@@ -128,6 +129,7 @@ class Mesh_Algorithm:
                     attr = algo_so_i.FindAttribute("AttributeIOR")[1]
                     if attr is not None:
                         anIOR = attr.Value()
                     attr = algo_so_i.FindAttribute("AttributeIOR")[1]
                     if attr is not None:
                         anIOR = attr.Value()
+                        if not anIOR: continue # prevent exception in orb.string_to_object()
                         algo_o_i = salome.orb.string_to_object(anIOR)
                         if algo_o_i is not None:
                             # Check if this is an algorithm
                         algo_o_i = salome.orb.string_to_object(anIOR)
                         if algo_o_i is not None:
                             # Check if this is an algorithm
index 680279e75c226a7341b0b1a2a854d059848eac09..a9b924724f4a96cb424121fd43a45c17b7d0a993 100644 (file)
@@ -1039,7 +1039,7 @@ namespace
     const vector< Handle(Geom_Curve) >& theCurves = theSinuFace._sinuCurves;
 
     double uMA;
     const vector< Handle(Geom_Curve) >& theCurves = theSinuFace._sinuCurves;
 
     double uMA;
-    SMESH_MAT2d::BoundaryPoint bp[2];
+    SMESH_MAT2d::BoundaryPoint bp[2]; // 2 sinuous sides
     const SMESH_MAT2d::Branch& branch = *theMA.getBranch(0);
     {
       // add to thePointsOnE NodePoint's of ends of theSinuEdges
     const SMESH_MAT2d::Branch& branch = *theMA.getBranch(0);
     {
       // add to thePointsOnE NodePoint's of ends of theSinuEdges
@@ -1138,7 +1138,7 @@ namespace
       // projection is set to the BoundaryPoint of this projection
 
       // evaluate distance to neighbor projections
       // projection is set to the BoundaryPoint of this projection
 
       // evaluate distance to neighbor projections
-      const double rShort = 0.2;
+      const double rShort = 0.33;
       bool isShortPrev[2], isShortNext[2], isPrevCloser[2];
       TMAPar2NPoints::iterator u2NPPrev = u2NP, u2NPNext = u2NP;
       --u2NPPrev; ++u2NPNext;
       bool isShortPrev[2], isShortNext[2], isPrevCloser[2];
       TMAPar2NPoints::iterator u2NPPrev = u2NP, u2NPNext = u2NP;
       --u2NPPrev; ++u2NPNext;
@@ -1306,8 +1306,8 @@ namespace
 
           TIterator u2NPprev = sameU2NP.front();
           TIterator u2NPnext = sameU2NP.back() ;
 
           TIterator u2NPprev = sameU2NP.front();
           TIterator u2NPnext = sameU2NP.back() ;
-          if ( u2NPprev->first > 0. ) --u2NPprev;
-          if ( u2NPnext->first < 1. ) ++u2NPprev;
+          if ( u2NPprev->first < 0. ) ++u2NPprev;
+          if ( u2NPnext->first > 1. ) --u2NPnext;
 
           set< int >::iterator edgeID = edgeInds.begin();
           for ( ; edgeID != edgeInds.end(); ++edgeID )
 
           set< int >::iterator edgeID = edgeInds.begin();
           for ( ; edgeID != edgeInds.end(); ++edgeID )
@@ -1322,8 +1322,8 @@ namespace
 
             if ( u0 == u1 )
             {
 
             if ( u0 == u1 )
             {
-              if ( np->_node ) --u2NPprev;
-              else             ++u2NPnext;
+              if ( u2NPprev != thePointsOnE.begin() ) --u2NPprev;
+              if ( u2NPnext != --thePointsOnE.end() ) ++u2NPnext;
               np = &get( u2NPprev->second, iSide );
               u0 = getUOnEdgeByPoint( *edgeID, np, theSinuFace );
               np = &get( u2NPnext->second, iSide );
               np = &get( u2NPprev->second, iSide );
               u0 = getUOnEdgeByPoint( *edgeID, np, theSinuFace );
               np = &get( u2NPnext->second, iSide );
@@ -1331,7 +1331,7 @@ namespace
             }
 
             // distribute points and create nodes
             }
 
             // distribute points and create nodes
-            double du = ( u1 - u0 ) / ( sameU2NP.size() + !existingNode );
+            double du = ( u1 - u0 ) / ( sameU2NP.size() + 1 /*!existingNode*/ );
             double u  = u0 + du;
             for ( size_t i = 0; i < sameU2NP.size(); ++i )
             {
             double u  = u0 + du;
             for ( size_t i = 0; i < sameU2NP.size(); ++i )
             {
@@ -1503,8 +1503,8 @@ namespace
         theFace._quad->side[ 1 ] = StdMeshers_FaceSide::New( uvsNew );
       }
 
         theFace._quad->side[ 1 ] = StdMeshers_FaceSide::New( uvsNew );
       }
 
-      if ( theFace._quad->side[ 1 ].NbPoints() !=
-           theFace._quad->side[ 3 ].NbPoints())
+      if ( theFace._quad->side[ 1 ].GetUVPtStruct().empty() ||
+           theFace._quad->side[ 3 ].GetUVPtStruct().empty() )
         return false;
 
     } // if ( theFace.IsRing() )
         return false;
 
     } // if ( theFace.IsRing() )
@@ -1553,6 +1553,7 @@ namespace
     vector< int >                edgeIDs   ( theSinuEdges.size() ); // IDs in the main shape
     vector< bool >               isComputed( theSinuEdges.size() );
     curves.resize( theSinuEdges.size(), 0 );
     vector< int >                edgeIDs   ( theSinuEdges.size() ); // IDs in the main shape
     vector< bool >               isComputed( theSinuEdges.size() );
     curves.resize( theSinuEdges.size(), 0 );
+    bool                         allComputed = true;
     for ( size_t i = 0; i < theSinuEdges.size(); ++i )
     {
       curves[i] = BRep_Tool::Curve( theSinuEdges[i], f,l );
     for ( size_t i = 0; i < theSinuEdges.size(); ++i )
     {
       curves[i] = BRep_Tool::Curve( theSinuEdges[i], f,l );
@@ -1561,6 +1562,8 @@ namespace
       SMESH_subMesh* sm = mesh->GetSubMesh( theSinuEdges[i] );
       edgeIDs   [i] = sm->GetId();
       isComputed[i] = ( !sm->IsEmpty() );
       SMESH_subMesh* sm = mesh->GetSubMesh( theSinuEdges[i] );
       edgeIDs   [i] = sm->GetId();
       isComputed[i] = ( !sm->IsEmpty() );
+      if ( !isComputed[i] )
+        allComputed = false;
     }
 
     const SMESH_MAT2d::Branch& branch = *theMA.getBranch(0);
     }
 
     const SMESH_MAT2d::Branch& branch = *theMA.getBranch(0);
@@ -1568,7 +1571,9 @@ namespace
 
     vector< std::size_t > edgeIDs1, edgeIDs2; // indices in theSinuEdges
     vector< SMESH_MAT2d::BranchPoint > divPoints;
 
     vector< std::size_t > edgeIDs1, edgeIDs2; // indices in theSinuEdges
     vector< SMESH_MAT2d::BranchPoint > divPoints;
-    branch.getOppositeGeomEdges( edgeIDs1, edgeIDs2, divPoints );
+    if ( !allComputed )
+      branch.getOppositeGeomEdges( edgeIDs1, edgeIDs2, divPoints );
+
     for ( size_t i = 0; i < edgeIDs1.size(); ++i )
       if ( isComputed[ edgeIDs1[i]] &&
            isComputed[ edgeIDs2[i]] )
     for ( size_t i = 0; i < edgeIDs1.size(); ++i )
       if ( isComputed[ edgeIDs1[i]] &&
            isComputed[ edgeIDs2[i]] )
@@ -1587,15 +1592,20 @@ namespace
           return false;
       }
 
           return false;
       }
 
-    // map param on MA to parameters of nodes on a pair of theSinuEdges
+    // map (param on MA) to (parameters of nodes on a pair of theSinuEdges)
     TMAPar2NPoints pointsOnE;
     vector<double> maParams;
     TMAPar2NPoints pointsOnE;
     vector<double> maParams;
+    set<int>       projectedEdges; // treated EDGEs which 'isComputed'
 
     // compute params of nodes on EDGEs by projecting division points from MA
 
     for ( size_t iEdgePair = 0; iEdgePair < edgeIDs1.size(); ++iEdgePair )
       // loop on pairs of opposite EDGEs
     {
 
     // compute params of nodes on EDGEs by projecting division points from MA
 
     for ( size_t iEdgePair = 0; iEdgePair < edgeIDs1.size(); ++iEdgePair )
       // loop on pairs of opposite EDGEs
     {
+      if ( projectedEdges.count( edgeIDs1[ iEdgePair ]) ||
+           projectedEdges.count( edgeIDs2[ iEdgePair ]) )
+        continue;
+
       // --------------------------------------------------------------------------------
       if ( isComputed[ edgeIDs1[ iEdgePair ]] !=                    // one EDGE is meshed
            isComputed[ edgeIDs2[ iEdgePair ]])
       // --------------------------------------------------------------------------------
       if ( isComputed[ edgeIDs1[ iEdgePair ]] !=                    // one EDGE is meshed
            isComputed[ edgeIDs2[ iEdgePair ]])
@@ -1610,6 +1620,8 @@ namespace
         if ( !SMESH_Algo::GetSortedNodesOnEdge( meshDS, theSinuEdges[ iEdgeComputed ], /*skipMedium=*/true, nodeParams ))
           return false;
 
         if ( !SMESH_Algo::GetSortedNodesOnEdge( meshDS, theSinuEdges[ iEdgeComputed ], /*skipMedium=*/true, nodeParams ))
           return false;
 
+        projectedEdges.insert( iEdgeComputed );
+
         SMESH_MAT2d::BoundaryPoint& bndPnt = bp[ 1-iSideComputed ];
         SMESH_MAT2d::BranchPoint brp;
         NodePoint npN, npB; // NodePoint's initialized by node and BoundaryPoint
         SMESH_MAT2d::BoundaryPoint& bndPnt = bp[ 1-iSideComputed ];
         SMESH_MAT2d::BranchPoint brp;
         NodePoint npN, npB; // NodePoint's initialized by node and BoundaryPoint
@@ -1618,10 +1630,10 @@ namespace
 
         double maParam1st, maParamLast, maParam;
         if ( !theMA.getBoundary().getBranchPoint( iEdgeComputed, nodeParams.begin()->first, brp ))
 
         double maParam1st, maParamLast, maParam;
         if ( !theMA.getBoundary().getBranchPoint( iEdgeComputed, nodeParams.begin()->first, brp ))
-            return false;
+          return false;
         branch.getParameter( brp, maParam1st );
         if ( !theMA.getBoundary().getBranchPoint( iEdgeComputed, nodeParams.rbegin()->first, brp ))
         branch.getParameter( brp, maParam1st );
         if ( !theMA.getBoundary().getBranchPoint( iEdgeComputed, nodeParams.rbegin()->first, brp ))
-            return false;
+          return false;
         branch.getParameter( brp, maParamLast );
 
         map< double, const SMDS_MeshNode* >::iterator u2n = nodeParams.begin(), u2nEnd = nodeParams.end();
         branch.getParameter( brp, maParamLast );
 
         map< double, const SMDS_MeshNode* >::iterator u2n = nodeParams.begin(), u2nEnd = nodeParams.end();
@@ -1641,28 +1653,6 @@ namespace
           npB = NodePoint( bndPnt );
           pos = pointsOnE.insert( hint, make_pair( maParam, make_pair( np0, np1 )));
         }
           npB = NodePoint( bndPnt );
           pos = pointsOnE.insert( hint, make_pair( maParam, make_pair( np0, np1 )));
         }
-
-        // move iEdgePair forward;
-        // find divPoints most close to max MA param
-        if ( edgeIDs1.size() > 1 )
-        {
-          maParamLast = pointsOnE.rbegin()->first;
-          int iClosest;
-          double minDist = 1.;
-          for ( ; iEdgePair < edgeIDs1.size()-1; ++iEdgePair )
-          {
-            branch.getParameter( divPoints[iEdgePair], maParam );
-            double d = Abs( maParamLast - maParam );
-            if ( d < minDist )
-              minDist = d, iClosest = iEdgePair;
-            else
-              break;
-          }
-          if ( Abs( maParamLast - 1. ) < minDist )
-            break; // the last pair treated
-          else
-            iEdgePair = iClosest;
-        }
       }
       // --------------------------------------------------------------------------------
       else if ( !isComputed[ edgeIDs1[ iEdgePair ]] &&         // none of EDGEs is meshed
       }
       // --------------------------------------------------------------------------------
       else if ( !isComputed[ edgeIDs1[ iEdgePair ]] &&         // none of EDGEs is meshed