Merge branch 'master' into V7_5_BR

This commit is contained in:
vsr 2015-01-12 13:24:59 +03:00
commit 2e9f6a1d33
13 changed files with 220 additions and 107 deletions

BIN
doc/salome/gui/SMESH/images/extrusionalongaline1.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 39 KiB

BIN
doc/salome/gui/SMESH/images/extrusionalongaline2.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 35 KiB

View File

@ -3,15 +3,18 @@
\page extrusion_page Extrusion
\n Extrusion is used to build mesh elements of plus one
dimension than the input ones. Any node, segment or 2D element can be
extruded. Each type of elements has a corresponding type of extruded elements:
dimension than the input ones. Boundary elements around elements of
plus one dimension are additionally created. All created elements
can be automatically grouped.
<p>Any node, segment or 2D element can be extruded. Each type of
elements is extruded into a corresponding type of result elements:
<table>
<tr><td><b>Extruded element</b></td><td><b> Result elements </b></td></tr>
<tr><td>Node </td><td> Segments </td></tr>
<tr><td>Segment </td><td> Quadrilaterals </td></tr>
<tr><td>Triangle </td><td> Pentahedrons </td></tr>
<tr><td>Quadrilateral </td><td> Hexahedrons </td></tr>
<tr><td>Polygon </td><td> Polyhedrons </td></tr>
<tr><td><b>Extruded element</b></td><td><b> Result element </b></td></tr>
<tr><td>Node </td><td> Segment </td></tr>
<tr><td>Segment </td><td> Quadrilateral </td></tr>
<tr><td>Triangle </td><td> Pentahedron </td></tr>
<tr><td>Quadrilateral </td><td> Hexahedron </td></tr>
<tr><td>Polygon </td><td> Polyhedron </td></tr>
<tr><td>Hexagonal polygon </td><td> Hexagonal prism </td></tr>
</table>
@ -35,7 +38,8 @@ The following dialog common for line and planar elements will appear:
<li>In this dialog:
<ul>
<li>Select the type of elements which will be extruded (0D, 1D or 2D).</li>
<li>Select the type of elements which will be extruded (nodes, 1D or
2D elements).</li>
<li>Specify the IDs of the elements which will be extruded by one
following means:
<ul>
@ -62,9 +66,15 @@ The following dialog common for line and planar elements will appear:
<li>specify the distance of extrusion along the vector.</li>
</ul>
<li>Specify the number of steps.</li>
<li>If you activate <b>Generate Groups</b> check-box, the created
elements contained in groups will be included into new groups named
by pattern "<old group name>_extruded" and "<old group name>_top".</li>
<li>If you activate <b>Generate Groups</b> check-box, the <em>result elements</em>
created from <em>extruded elements</em> contained in groups will be
included into new groups named by pattern "<old group
name>_extruded" and "<old group name>_top". For example if an
extruded quadrangle is included in \a Group_1 group then result
hexahedra will be included in \a Group_1_extruded group and a
quadrangle created at the "top" of extruded mesh will
be included in \a Group_1_top group. <br>This check-box is active
only if there are some groups in the mesh.</li>
</ul>
<li>Click \b Apply or <b> Apply and Close</b> button to confirm the operation.</li>

View File

@ -393,12 +393,13 @@ SMESH_DeviceActor
vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
aCellTypesArray->SetNumberOfComponents( 1 );
aCellTypesArray->Allocate( aNbCells * aCellTypesArray->GetNumberOfComponents() );
vtkIdList *anIdList = vtkIdList::New();
anIdList->SetNumberOfIds(2);
Length2D::TValues::const_iterator anIter = aValues.begin();
for(vtkIdType aVtkId = 0; anIter != aValues.end(); anIter++,aVtkId++){
aNbCells = 0;
for(; anIter != aValues.end(); anIter++){
const Length2D::Value& aValue = *anIter;
int aNode[2] = {
myVisualObj->GetNodeVTKId(aValue.myPntId[0]),
@ -409,27 +410,30 @@ SMESH_DeviceActor
anIdList->SetId( 1, aNode[1] );
aConnectivity->InsertNextCell( anIdList );
aCellTypesArray->InsertNextValue( VTK_LINE );
aScalars->SetValue(aVtkId,aValue.myLength);
aScalars->SetValue(aNbCells,aValue.myLength);
aNbCells++;
}
}
aCellTypesArray->SetNumberOfTuples( aNbCells );
aScalars->SetNumberOfTuples( aNbCells );
VTKViewer_CellLocationsArray* aCellLocationsArray = VTKViewer_CellLocationsArray::New();
aCellLocationsArray->SetNumberOfComponents( 1 );
aCellLocationsArray->SetNumberOfTuples( aNbCells );
aConnectivity->InitTraversal();
for( vtkIdType idType = 0, *pts, npts; aConnectivity->GetNextCell( npts, pts ); idType++ )
aCellLocationsArray->SetValue( idType, aConnectivity->GetTraversalLocation( npts ) );
aDataSet->SetCells( aCellTypesArray, aCellLocationsArray,aConnectivity );
aDataSet->SetCells( aCellTypesArray, aCellLocationsArray, aConnectivity );
SetUnstructuredGrid(aDataSet);
aDataSet->GetCellData()->SetScalars(aScalars);
aScalars->Delete();
theLookupTable->SetRange(aScalars->GetRange());
theLookupTable->Build();
myMergeFilter->SetScalarsData(aDataSet);
aDataSet->Delete();
}
@ -449,16 +453,17 @@ SMESH_DeviceActor
vtkIdType aCellsSize = 3*aNbCells;
vtkCellArray* aConnectivity = vtkCellArray::New();
aConnectivity->Allocate( aCellsSize, 0 );
vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
aCellTypesArray->SetNumberOfComponents( 1 );
aCellTypesArray->Allocate( aNbCells * aCellTypesArray->GetNumberOfComponents() );
vtkIdList *anIdList = vtkIdList::New();
anIdList->SetNumberOfIds(2);
MultiConnection2D::MValues::const_iterator anIter = aValues.begin();
for(vtkIdType aVtkId = 0; anIter != aValues.end(); anIter++,aVtkId++){
aNbCells = 0;
for(; anIter != aValues.end(); anIter++){
const MultiConnection2D::Value& aValue = (*anIter).first;
int aNode[2] = {
myVisualObj->GetNodeVTKId(aValue.myPntId[0]),
@ -469,27 +474,30 @@ SMESH_DeviceActor
anIdList->SetId( 1, aNode[1] );
aConnectivity->InsertNextCell( anIdList );
aCellTypesArray->InsertNextValue( VTK_LINE );
aScalars->SetValue(aVtkId,(*anIter).second);
aScalars->SetValue( aNbCells,(*anIter).second);
aNbCells++;
}
}
aCellTypesArray->SetNumberOfTuples( aNbCells );
aScalars->SetNumberOfTuples( aNbCells );
VTKViewer_CellLocationsArray* aCellLocationsArray = VTKViewer_CellLocationsArray::New();
aCellLocationsArray->SetNumberOfComponents( 1 );
aCellLocationsArray->SetNumberOfTuples( aNbCells );
aConnectivity->InitTraversal();
for( vtkIdType idType = 0, *pts, npts; aConnectivity->GetNextCell( npts, pts ); idType++ )
aCellLocationsArray->SetValue( idType, aConnectivity->GetTraversalLocation( npts ) );
aDataSet->SetCells( aCellTypesArray, aCellLocationsArray,aConnectivity );
SetUnstructuredGrid(aDataSet);
aDataSet->GetCellData()->SetScalars(aScalars);
aScalars->Delete();
theLookupTable->SetRange(aScalars->GetRange());
theLookupTable->Build();
myMergeFilter->SetScalarsData(aDataSet);
aDataSet->Delete();
}

View File

@ -10229,6 +10229,7 @@ bool SMESH_MeshEditor::doubleNodes( SMESHDS_Mesh* theMeshDS,
{
// duplicate node
aNewNode = theMeshDS->AddNode( aCurrNode->X(), aCurrNode->Y(), aCurrNode->Z() );
copyPosition( aCurrNode, aNewNode );
theNodeNodeMap[ aCurrNode ] = aNewNode;
myLastCreatedNodes.Append( aNewNode );
}
@ -10241,10 +10242,8 @@ bool SMESH_MeshEditor::doubleNodes( SMESHDS_Mesh* theMeshDS,
if ( theIsDoubleElem )
AddElement(newNodes, anElem->GetType(), anElem->IsPoly());
else
{
MESSAGE("ChangeElementNodes");
theMeshDS->ChangeElementNodes( anElem, &newNodes[ 0 ], anElem->NbNodes() );
}
res = true;
}
return res;
@ -10255,8 +10254,8 @@ bool SMESH_MeshEditor::doubleNodes( SMESHDS_Mesh* theMeshDS,
\brief Creates a hole in a mesh by doubling the nodes of some particular elements
\param theNodes - identifiers of nodes to be doubled
\param theModifiedElems - identifiers of elements to be updated by the new (doubled)
nodes. If list of element identifiers is empty then nodes are doubled but
they not assigned to elements
nodes. If list of element identifiers is empty then nodes are doubled but
they not assigned to elements
\return TRUE if operation has been completed successfully, FALSE otherwise
*/
//================================================================================
@ -10292,6 +10291,7 @@ bool SMESH_MeshEditor::DoubleNodes( const std::list< int >& theListOfNodes,
const SMDS_MeshNode* aNewNode = aMeshDS->AddNode( aNode->X(), aNode->Y(), aNode->Z() );
if ( aNewNode )
{
copyPosition( aNode, aNewNode );
anOldNodeToNewNode[ aNode ] = aNewNode;
myLastCreatedNodes.Append( aNewNode );
}
@ -10910,6 +10910,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
}
double *coords = grid->GetPoint(oldId);
SMDS_MeshNode *newNode = meshDS->AddNode(coords[0], coords[1], coords[2]);
copyPosition( meshDS->FindNodeVtk( oldId ), newNode );
int newId = newNode->getVtkId();
nodeDomains[oldId][idom] = newId; // cloned node for other domains
//MESSAGE("-+-+-c oldNode " << oldId << " domain " << idomain << " newNode " << newId << " domain " << idom << " size=" <<nodeDomains[oldId].size());
@ -11248,6 +11249,14 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
}
}
// Remove empty groups (issue 0022812)
std::map<std::string, SMESH_Group*>::iterator name_group = mapOfJunctionGroups.begin();
for ( ; name_group != mapOfJunctionGroups.end(); ++name_group )
{
if ( name_group->second && name_group->second->GetGroupDS()->IsEmpty() )
myMesh->RemoveGroup( name_group->second->GetGroupDS()->GetID() );
}
meshDS->CleanDownWardConnectivity(); // Mesh has been modified, downward connectivity is no more usable, free memory
grid->BuildLinks();
@ -11315,6 +11324,7 @@ bool SMESH_MeshEditor::CreateFlatElementsOnFacesGroups(const std::vector<TIDSort
if (!clonedNodes.count(node))
{
clone = meshDS->AddNode(node->X(), node->Y(), node->Z());
copyPosition( node, clone );
clonedNodes[node] = clone;
}
else
@ -11331,6 +11341,7 @@ bool SMESH_MeshEditor::CreateFlatElementsOnFacesGroups(const std::vector<TIDSort
if (!intermediateNodes.count(node))
{
inter = meshDS->AddNode(node->X(), node->Y(), node->Z());
copyPosition( node, inter );
intermediateNodes[node] = inter;
}
else
@ -12275,3 +12286,45 @@ int SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements,
}
return nbAddedBnd;
}
//================================================================================
/*!
* \brief Copy node position and set \a to node on the same geometry
*/
//================================================================================
void SMESH_MeshEditor::copyPosition( const SMDS_MeshNode* from,
const SMDS_MeshNode* to )
{
if ( !from || !to ) return;
SMDS_PositionPtr pos = from->GetPosition();
if ( !pos || from->getshapeId() < 1 ) return;
switch ( pos->GetTypeOfPosition() )
{
case SMDS_TOP_3DSPACE: break;
case SMDS_TOP_FACE:
{
const SMDS_FacePosition* fPos = static_cast< const SMDS_FacePosition* >( pos );
GetMeshDS()->SetNodeOnFace( to, from->getshapeId(),
fPos->GetUParameter(), fPos->GetVParameter() );
break;
}
case SMDS_TOP_EDGE:
{
// WARNING: it is dangerous to set equal nodes on one EDGE!!!!!!!!
const SMDS_EdgePosition* ePos = static_cast< const SMDS_EdgePosition* >( pos );
GetMeshDS()->SetNodeOnEdge( to, from->getshapeId(), ePos->GetUParameter() );
break;
}
case SMDS_TOP_VERTEX:
{
GetMeshDS()->SetNodeOnVertex( to, from->getshapeId() );
break;
}
case SMDS_TOP_UNSPEC:
default:;
}
}

View File

@ -686,6 +686,9 @@ public:
std::map< const SMDS_MeshNode*, const SMDS_MeshNode* >& theNodeNodeMap,
const bool theIsDoubleElem );
void copyPosition( const SMDS_MeshNode* from,
const SMDS_MeshNode* to );
private:
SMESH_Mesh * myMesh;

View File

@ -259,6 +259,7 @@ void SMESH_MesherHelper::SetSubShape(const TopoDS_Shape& aSh)
{
// look for a "seam" edge, a real seam or an edge on period boundary
TopoDS_Edge edge = TopoDS::Edge( exp.Current() );
const int edgeID = meshDS->ShapeToIndex( edge );
if ( myParIndex )
{
BRep_Tool::UVPoints( edge, face, uv1, uv2 );
@ -305,7 +306,6 @@ void SMESH_MesherHelper::SetSubShape(const TopoDS_Shape& aSh)
if ( isSeam )
{
// store seam shape indices, negative if shape encounters twice
int edgeID = meshDS->ShapeToIndex( edge );
mySeamShapeIds.insert( IsSeamShape( edgeID ) ? -edgeID : edgeID );
for ( TopExp_Explorer v( edge, TopAbs_VERTEX ); v.More(); v.Next() ) {
int vertexID = meshDS->ShapeToIndex( v.Current() );
@ -315,10 +315,15 @@ void SMESH_MesherHelper::SetSubShape(const TopoDS_Shape& aSh)
}
// look for a degenerated edge
if ( SMESH_Algo::isDegenerated( edge )) {
myDegenShapeIds.insert( meshDS->ShapeToIndex( edge ));
myDegenShapeIds.insert( edgeID );
for ( TopExp_Explorer v( edge, TopAbs_VERTEX ); v.More(); v.Next() )
myDegenShapeIds.insert( meshDS->ShapeToIndex( v.Current() ));
}
if ( !BRep_Tool::SameParameter( edge ) ||
!BRep_Tool::SameRange( edge ))
{
setPosOnShapeValidity( edgeID, false );
}
}
}
}
@ -527,11 +532,11 @@ void SMESH_MesherHelper::ToFixNodeParameters(bool toFix)
//=======================================================================
//function : GetUVOnSeam
//function : getUVOnSeam
//purpose : Select UV on either of 2 pcurves of a seam edge, closest to the given UV
//=======================================================================
gp_Pnt2d SMESH_MesherHelper::GetUVOnSeam( const gp_Pnt2d& uv1, const gp_Pnt2d& uv2 ) const
gp_Pnt2d SMESH_MesherHelper::getUVOnSeam( const gp_Pnt2d& uv1, const gp_Pnt2d& uv2 ) const
{
gp_Pnt2d result = uv1;
for ( int i = U_periodic; i <= V_periodic ; ++i )
@ -568,38 +573,34 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face& F,
const SMDS_PositionPtr Pos = n->GetPosition();
bool uvOK = false;
if(Pos->GetTypeOfPosition()==SMDS_TOP_FACE)
if ( Pos->GetTypeOfPosition() == SMDS_TOP_FACE )
{
// node has position on face
const SMDS_FacePosition* fpos =
static_cast<const SMDS_FacePosition*>( Pos );
uv.SetCoord(fpos->GetUParameter(),fpos->GetVParameter());
const SMDS_FacePosition* fpos = static_cast<const SMDS_FacePosition*>( Pos );
uv.SetCoord( fpos->GetUParameter(), fpos->GetVParameter() );
if ( check )
uvOK = CheckNodeUV( F, n, uv.ChangeCoord(), 10*MaxTolerance( F ));
uvOK = CheckNodeUV( F, n, uv.ChangeCoord(), 10*getFaceMaxTol( F ));
}
else if(Pos->GetTypeOfPosition()==SMDS_TOP_EDGE)
else if ( Pos->GetTypeOfPosition() == SMDS_TOP_EDGE )
{
// node has position on edge => it is needed to find
// corresponding edge from face, get pcurve for this
// edge and retrieve value from this pcurve
const SMDS_EdgePosition* epos =
static_cast<const SMDS_EdgePosition*>( Pos );
int edgeID = n->getshapeId();
TopoDS_Edge E = TopoDS::Edge(GetMeshDS()->IndexToShape(edgeID));
// node has position on EDGE => it is needed to find
// corresponding EDGE from FACE, get pcurve for this
// EDGE and retrieve value from this pcurve
const SMDS_EdgePosition* epos = static_cast<const SMDS_EdgePosition*>( Pos );
const int edgeID = n->getshapeId();
const TopoDS_Edge& E = TopoDS::Edge( GetMeshDS()->IndexToShape( edgeID ));
double f, l, u = epos->GetUParameter();
Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
bool validU = ( f < u && u < l );
if ( validU )
uv = C2d->Value( u );
else
uv.SetCoord( Precision::Infinite(),0.);
Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface( E, F, f, l );
bool validU = ( !C2d.IsNull() && ( f < u ) && ( u < l ));
if ( validU ) uv = C2d->Value( u );
else uv.SetCoord( Precision::Infinite(),0.);
if ( check || !validU )
uvOK = CheckNodeUV( F, n, uv.ChangeCoord(), 10*MaxTolerance( F ),/*force=*/ !validU );
uvOK = CheckNodeUV( F, n, uv.ChangeCoord(), 10*getFaceMaxTol( F ),/*force=*/ !validU );
// for a node on a seam edge select one of UVs on 2 pcurves
if ( n2 && IsSeamShape( edgeID ) )
// for a node on a seam EDGE select one of UVs on 2 pcurves
if ( n2 && IsSeamShape( edgeID ))
{
uv = GetUVOnSeam( uv, GetNodeUV( F, n2, 0, check ));
uv = getUVOnSeam( uv, GetNodeUV( F, n2, 0, check ));
}
else
{ // adjust uv to period
@ -611,23 +612,22 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face& F,
if ( isUPeriodic || isVPeriodic ) {
Standard_Real UF,UL,VF,VL;
S->Bounds(UF,UL,VF,VL);
if ( isUPeriodic )
newUV.SetX( uv.X() + ShapeAnalysis::AdjustToPeriod(uv.X(),UF,UL));
if ( isVPeriodic )
newUV.SetY( uv.Y() + ShapeAnalysis::AdjustToPeriod(uv.Y(),VF,VL));
}
if ( n2 )
{
gp_Pnt2d uv2 = GetNodeUV( F, n2, 0, check );
if ( isUPeriodic && Abs( uv.X()-uv2.X() ) < Abs( newUV.X()-uv2.X() ))
newUV.SetX( uv.X() );
if ( isVPeriodic && Abs( uv.Y()-uv2.Y() ) < Abs( newUV.Y()-uv2.Y() ))
newUV.SetY( uv.Y() );
if ( isUPeriodic ) newUV.SetX( uv.X() + ShapeAnalysis::AdjustToPeriod(uv.X(),UF,UL));
if ( isVPeriodic ) newUV.SetY( uv.Y() + ShapeAnalysis::AdjustToPeriod(uv.Y(),VF,VL));
if ( n2 )
{
gp_Pnt2d uv2 = GetNodeUV( F, n2, 0, check );
if ( isUPeriodic && Abs( uv.X()-uv2.X() ) < Abs( newUV.X()-uv2.X() ))
newUV.SetX( uv.X() );
if ( isVPeriodic && Abs( uv.Y()-uv2.Y() ) < Abs( newUV.Y()-uv2.Y() ))
newUV.SetY( uv.Y() );
}
}
uv = newUV;
}
}
else if(Pos->GetTypeOfPosition()==SMDS_TOP_VERTEX)
else if ( Pos->GetTypeOfPosition() == SMDS_TOP_VERTEX )
{
if ( int vertexID = n->getshapeId() ) {
const TopoDS_Vertex& V = TopoDS::Vertex(GetMeshDS()->IndexToShape(vertexID));
@ -646,7 +646,7 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face& F,
// get UV of a vertex closest to the node
double dist = 1e100;
gp_Pnt pn = XYZ( n );
for ( TopExp_Explorer vert(F,TopAbs_VERTEX); !uvOK && vert.More(); vert.Next() ) {
for ( TopExp_Explorer vert( F,TopAbs_VERTEX ); !uvOK && vert.More(); vert.Next() ) {
TopoDS_Vertex curV = TopoDS::Vertex( vert.Current() );
gp_Pnt p = BRep_Tool::Pnt( curV );
double curDist = p.SquareDistance( pn );
@ -675,13 +675,23 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face& F,
}
}
}
if ( n2 && IsSeamShape( vertexID ) )
uv = GetUVOnSeam( uv, GetNodeUV( F, n2, 0 ));
if ( n2 && IsSeamShape( vertexID ))
{
bool isSeam = ( myShape.IsSame( F ));
if ( !isSeam ) {
SMESH_MesherHelper h( *myMesh );
h.SetSubShape( F );
isSeam = IsSeamShape( vertexID );
}
if ( isSeam )
uv = getUVOnSeam( uv, GetNodeUV( F, n2, 0 ));
}
}
}
else
{
uvOK = CheckNodeUV( F, n, uv.ChangeCoord(), 10*MaxTolerance( F ));
uvOK = CheckNodeUV( F, n, uv.ChangeCoord(), 10*getFaceMaxTol( F ));
}
if ( check )
@ -750,7 +760,7 @@ bool SMESH_MesherHelper::CheckNodeUV(const TopoDS_Face& F,
const_cast<SMDS_MeshNode*>(n)->SetPosition
( SMDS_PositionPtr( new SMDS_FacePosition( U, V )));
}
else if ( uv.Modulus() > numeric_limits<double>::min() )
else if ( myShape.IsSame(F) && uv.Modulus() > numeric_limits<double>::min() )
{
setPosOnShapeValidity( shapeID, true );
}
@ -1037,9 +1047,12 @@ bool SMESH_MesherHelper::CheckNodeU(const TopoDS_Edge& E,
//=======================================================================
//function : GetMediumPos
//purpose : Return index and type of the shape (EDGE or FACE only) to
// set a medium node on
// set a medium node on
//param : useCurSubShape - if true, returns the shape set via SetSubShape()
// if any
// calling GetMediumPos() with useCurSubShape=true is OK only for the
// case where the lower dim mesh is already constructed and converted to quadratic,
// else, nodes on EDGEs are assigned to FACE, for example.
//=======================================================================
std::pair<int, TopAbs_ShapeEnum>
@ -1442,11 +1455,9 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetMediumNode(const SMDS_MeshNode* n1,
TopoDS_Edge E; double u [2];
TopoDS_Face F; gp_XY uv[2];
bool uvOK[2] = { false, false };
const bool useCurSubShape = ( !myShape.IsNull() && myShape.ShapeType() == TopAbs_EDGE );
pair<int, TopAbs_ShapeEnum> pos = GetMediumPos( n1, n2, mySetElemOnShape );
// calling GetMediumPos() with useCurSubShape=mySetElemOnShape is OK only for the
// case where the lower dim mesh is already constructed, else, nodes on EDGEs are
// assigned to FACE, for example.
pair<int, TopAbs_ShapeEnum> pos = GetMediumPos( n1, n2, useCurSubShape );
// get positions of the given nodes on shapes
if ( pos.second == TopAbs_FACE )
@ -2848,6 +2859,24 @@ double SMESH_MesherHelper::MaxTolerance( const TopoDS_Shape& shape )
return tol;
}
//================================================================================
/*!
* \brief Return MaxTolerance( face ), probably cached
*/
//================================================================================
double SMESH_MesherHelper::getFaceMaxTol( const TopoDS_Shape& face ) const
{
int faceID = GetMeshDS()->ShapeToIndex( face );
SMESH_MesherHelper* me = const_cast< SMESH_MesherHelper* >( this );
double & tol = me->myFaceMaxTol.insert( make_pair( faceID, -1. )).first->second;
if ( tol < 0 )
tol = MaxTolerance( face );
return tol;
}
//================================================================================
/*!
* \brief Return an angle between two EDGEs sharing a common VERTEX with reference
@ -4606,6 +4635,8 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError,
// 3. Compute displacement of medium nodes
// ---------------------------------------
SMESH_MesherHelper faceHlp(*myMesh);
// two loops on QFaces: the first is to treat boundary links, the second is for internal ones.
TopLoc_Location loc;
bool checkUV;
@ -4689,22 +4720,23 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError,
TopoDS_Face face;
if ( !isInside )
{
// compute node displacement of end links of chain in parametric space of face
// compute node displacement of end links of chain in parametric space of FACE
TChainLink& linkOnFace = *(++chain.begin());
const SMDS_MeshNode* nodeOnFace = linkOnFace->_mediumNode;
TopoDS_Shape f = GetSubShapeByNode( nodeOnFace, GetMeshDS() );
if ( !f.IsNull() && f.ShapeType() == TopAbs_FACE )
{
face = TopoDS::Face( f );
faceHlp.SetSubShape( face );
Handle(Geom_Surface) surf = BRep_Tool::Surface(face,loc);
bool isStraight[2];
for ( int is1 = 0; is1 < 2; ++is1 ) // move0 or move1
{
TChainLink& link = is1 ? chain.back() : chain.front();
gp_XY uvm = GetNodeUV( face, link->_mediumNode, nodeOnFace, &checkUV);
gp_XY uv1 = GetNodeUV( face, link->node1(), nodeOnFace, &checkUV);
gp_XY uv2 = GetNodeUV( face, link->node2(), nodeOnFace, &checkUV);
gp_XY uv12 = GetMiddleUV( surf, uv1, uv2);
gp_XY uvm = faceHlp.GetNodeUV( face, link->_mediumNode, nodeOnFace, &checkUV );
gp_XY uv1 = faceHlp.GetNodeUV( face, link->node1(), nodeOnFace, &checkUV );
gp_XY uv2 = faceHlp.GetNodeUV( face, link->node2(), nodeOnFace, &checkUV );
gp_XY uv12 = faceHlp.GetMiddleUV( surf, uv1, uv2 );
// uvMove = uvm - uv12
gp_XY uvMove = applyIn2D(surf, uvm, uv12, gp_XY_Subtracted, /*inPeriod=*/false);
( is1 ? move1 : move0 ).SetCoord( uvMove.X(), uvMove.Y(), 0 );
@ -4719,10 +4751,10 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError,
}
// check if a chain is already fixed
gp_XY uvm = GetNodeUV( face, linkOnFace->_mediumNode, 0, &checkUV);
gp_XY uv1 = GetNodeUV( face, linkOnFace->node1(), nodeOnFace, &checkUV);
gp_XY uv2 = GetNodeUV( face, linkOnFace->node2(), nodeOnFace, &checkUV);
gp_XY uv12 = GetMiddleUV( surf, uv1, uv2);
gp_XY uvm = faceHlp.GetNodeUV( face, linkOnFace->_mediumNode, 0, &checkUV );
gp_XY uv1 = faceHlp.GetNodeUV( face, linkOnFace->node1(), nodeOnFace, &checkUV );
gp_XY uv2 = faceHlp.GetNodeUV( face, linkOnFace->node2(), nodeOnFace, &checkUV );
gp_XY uv12 = faceHlp.GetMiddleUV( surf, uv1, uv2 );
if (( uvm - uv12 ).SquareModulus() > 1e-10 )
{
MSG("Already fixed - ignore");
@ -4767,8 +4799,8 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError,
else {
// compute 3D displacement by 2D one
Handle(Geom_Surface) s = BRep_Tool::Surface(face,loc);
gp_XY oldUV = GetNodeUV( face, (*link1)->_mediumNode, 0, &checkUV);
gp_XY newUV = applyIn2D( s, oldUV, gp_XY( move.X(),move.Y()), gp_XY_Added);
gp_XY oldUV = faceHlp.GetNodeUV( face, (*link1)->_mediumNode, 0, &checkUV );
gp_XY newUV = applyIn2D( s, oldUV, gp_XY( move.X(),move.Y()), gp_XY_Added );
gp_Pnt newPnt = s->Value( newUV.X(), newUV.Y());
move = gp_Vec( XYZ((*link1)->_mediumNode), newPnt.Transformed(loc) );
if ( SMDS_FacePosition* nPos =
@ -4778,8 +4810,8 @@ void SMESH_MesherHelper::FixQuadraticElements(SMESH_ComputeErrorPtr& compError,
if ( (XYZ((*link1)->node1()) - XYZ((*link1)->node2())).SquareModulus() <
move.SquareMagnitude())
{
gp_XY uv0 = GetNodeUV( face, (*link0)->_mediumNode, 0, &checkUV);
gp_XY uv2 = GetNodeUV( face, (*link2)->_mediumNode, 0, &checkUV);
gp_XY uv0 = faceHlp.GetNodeUV( face, (*link0)->_mediumNode, 0, &checkUV );
gp_XY uv2 = faceHlp.GetNodeUV( face, (*link2)->_mediumNode, 0, &checkUV );
MSG( "TOO LONG MOVE \t" <<
"uv0: "<<uv0.X()<<", "<<uv0.Y()<<" \t" <<
"uv2: "<<uv2.X()<<", "<<uv2.Y()<<" \t" <<

View File

@ -671,11 +671,14 @@ public:
* \param uv2 - UV within a face
* \retval gp_Pnt2d - selected UV
*/
gp_Pnt2d GetUVOnSeam( const gp_Pnt2d& uv1, const gp_Pnt2d& uv2 ) const;
gp_Pnt2d getUVOnSeam( const gp_Pnt2d& uv1, const gp_Pnt2d& uv2 ) const;
const SMDS_MeshNode* getMediumNodeOnComposedWire(const SMDS_MeshNode* n1,
const SMDS_MeshNode* n2,
bool force3d);
double getFaceMaxTol( const TopoDS_Shape& face ) const;
private:
// Forbiden copy constructor
@ -710,9 +713,11 @@ public:
double myPar1[2], myPar2[2]; // U and V bounds of a closed periodic surface
int myParIndex; // bounds' index (1-U, 2-V, 3-both)
typedef std::map< int, GeomAPI_ProjectPointOnSurf* > TID2ProjectorOnSurf;
TID2ProjectorOnSurf myFace2Projector;
std::map< int, double > myFaceMaxTol;
typedef std::map< int, GeomAPI_ProjectPointOnSurf* > TID2ProjectorOnSurf;
typedef std::map< int, GeomAPI_ProjectPointOnCurve* > TID2ProjectorOnCurve;
TID2ProjectorOnSurf myFace2Projector;
TID2ProjectorOnCurve myEdge2Projector;
TopoDS_Shape myShape;

View File

@ -602,7 +602,7 @@ void SMESHGUI_DuplicateNodesDlg::onSelectionChanged()
break;
case 3:
ok = ( aGroupType == SMESH::VOLUME ||
aGroupType == SMESH::FACE );
aGroupType == SMESH::FACE );
break;
}
}

View File

@ -860,7 +860,7 @@ void SMESHGUI_ExtrusionDlg::SelectionIntoArgument()
else
return;
} else {
// get indices of selcted elements
// get indices of selected elements
TColStd_IndexedMapOfInteger aMapIndex;
mySelector->GetIndex(IO,aMapIndex);
aNbElements = aMapIndex.Extent();

View File

@ -3391,7 +3391,7 @@ class Mesh:
# @param theSubMesh a group or a sub-mesh to convert; WARNING: in this case the mesh can become not conformal
# @param theToBiQuad If True, converts the mesh to bi-quadratic
# @ingroup l2_modif_tofromqu
def ConvertToQuadratic(self, theForce3d, theSubMesh=None, theToBiQuad=False):
def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False):
if isinstance( theSubMesh, Mesh ):
theSubMesh = theSubMesh.mesh
if theToBiQuad:

View File

@ -213,7 +213,7 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
existingNodes.insert( n );
}
// get EDGESs and their ids and get existing nodes on EDGEs
// get EDGEs and their ids and get existing nodes on EDGEs
vector< TopoDS_Edge > edges;
for ( exp.Init( theShape, TopAbs_EDGE ); exp.More(); exp.Next() )
{

View File

@ -216,6 +216,8 @@ bool StdMeshers_LocalLength::SetParametersByMesh(const SMESH_Mesh* theMesh,
{
const TopoDS_Edge& edge = TopoDS::Edge( edgeMap( iE ));
Handle(Geom_Curve) C = BRep_Tool::Curve( edge, L, UMin, UMax );
if ( C.IsNull() )
continue;
GeomAdaptor_Curve AdaptCurve(C, UMin, UMax);
vector< double > params;