mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2025-01-27 20:20:33 +05:00
23179: EDF 11603 - Problem with extrusion when path is not well oriented
HYDRO module: Feature #523: river, channel, embankment meshing
This commit is contained in:
parent
0c1e70a38f
commit
512d3547bc
Binary file not shown.
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 6.0 KiB |
@ -229,6 +229,9 @@ have been defined will be discretized.
|
||||
</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
|
||||
|
@ -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
|
||||
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
|
||||
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"
|
||||
|
||||
|
@ -441,7 +441,8 @@ void SMESH_Gen::setCurrentSubMesh(SMESH_subMesh* sm)
|
||||
{
|
||||
if ( sm )
|
||||
_sm_current.push_back( sm );
|
||||
else
|
||||
|
||||
else if ( !_sm_current.empty() )
|
||||
_sm_current.pop_back();
|
||||
}
|
||||
|
||||
|
@ -5986,6 +5986,10 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet theElements[2],
|
||||
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() ) {
|
||||
|
@ -344,6 +344,9 @@ namespace
|
||||
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 )
|
||||
@ -367,8 +370,8 @@ namespace
|
||||
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;
|
||||
}
|
||||
@ -413,7 +416,7 @@ namespace
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
void bndSegsToMesh( const vector< BndSeg >& bndSegs )
|
||||
void bndSegsToMesh( const vector< vector< BndSeg > >& bndSegsPerEdge )
|
||||
{
|
||||
#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";
|
||||
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";
|
||||
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";
|
||||
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 << "e" << i << " = m.AddEdge([ n" << n0 << ", n" << n1 << " ])\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
text << "\n";
|
||||
@ -985,7 +992,7 @@ namespace
|
||||
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
|
||||
@ -1374,6 +1381,15 @@ bool SMESH_MAT2d::Boundary::getBranchPoint( const std::size_t iEdge,
|
||||
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
|
||||
|
@ -947,7 +947,8 @@ std::string SMESH_GroupOnFilter_i::FilterToString() const
|
||||
{
|
||||
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 ))
|
||||
|
@ -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 ( !aSubMesh || !aSubMesh->GetSubMeshDS() )
|
||||
if ( !aSubMesh /*|| !aSubMesh->GetSubMeshDS()*/ )
|
||||
return aGroups._retn();
|
||||
}
|
||||
|
||||
|
@ -1100,8 +1100,7 @@ class StdMeshersBuilder_Prism3D(Mesh_Algorithm):
|
||||
|
||||
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)
|
||||
#
|
||||
@ -1133,30 +1132,12 @@ class StdMeshersBuilder_RadialPrism3D(StdMeshersBuilder_Prism3D):
|
||||
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):
|
||||
class StdMeshersBuilder_RadialAlgorithm(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"
|
||||
|
||||
## 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)
|
||||
self.Create(mesh, geom, self.algoType)
|
||||
|
||||
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
|
||||
|
||||
## 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
|
||||
class StdMeshersBuilder_QuadMA_1D2D(Mesh_Algorithm):
|
||||
class StdMeshersBuilder_QuadMA_1D2D(StdMeshersBuilder_RadialAlgorithm):
|
||||
|
||||
## 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):
|
||||
Mesh_Algorithm.__init__(self)
|
||||
StdMeshersBuilder_RadialAlgorithm.__init__(self)
|
||||
self.Create(mesh, geom, self.algoType)
|
||||
pass
|
||||
|
||||
|
@ -3987,6 +3987,7 @@ class Mesh:
|
||||
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()
|
||||
@ -4019,8 +4020,9 @@ class Mesh:
|
||||
# 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
|
||||
@ -4050,7 +4052,7 @@ class Mesh:
|
||||
# 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,
|
||||
@ -4080,7 +4082,7 @@ class Mesh:
|
||||
# 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,
|
||||
@ -4109,7 +4111,7 @@ class Mesh:
|
||||
# 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,
|
||||
@ -4138,7 +4140,7 @@ class Mesh:
|
||||
# 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,
|
||||
|
@ -85,6 +85,7 @@ class Mesh_Algorithm:
|
||||
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
|
||||
@ -128,6 +129,7 @@ class Mesh_Algorithm:
|
||||
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
|
||||
|
@ -1039,7 +1039,7 @@ namespace
|
||||
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
|
||||
@ -1138,7 +1138,7 @@ namespace
|
||||
// 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;
|
||||
@ -1306,8 +1306,8 @@ namespace
|
||||
|
||||
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 )
|
||||
@ -1322,8 +1322,8 @@ namespace
|
||||
|
||||
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 );
|
||||
@ -1331,7 +1331,7 @@ namespace
|
||||
}
|
||||
|
||||
// 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 )
|
||||
{
|
||||
@ -1503,8 +1503,8 @@ namespace
|
||||
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() )
|
||||
@ -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 );
|
||||
bool allComputed = true;
|
||||
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() );
|
||||
if ( !isComputed[i] )
|
||||
allComputed = false;
|
||||
}
|
||||
|
||||
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;
|
||||
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]] )
|
||||
@ -1587,15 +1592,20 @@ namespace
|
||||
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;
|
||||
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
|
||||
{
|
||||
if ( projectedEdges.count( edgeIDs1[ iEdgePair ]) ||
|
||||
projectedEdges.count( edgeIDs2[ iEdgePair ]) )
|
||||
continue;
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
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;
|
||||
|
||||
projectedEdges.insert( iEdgeComputed );
|
||||
|
||||
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 ))
|
||||
return false;
|
||||
return false;
|
||||
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();
|
||||
@ -1641,28 +1653,6 @@ namespace
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user