//=======================================================================
//function : IsQuadraticSubMesh
-//purpose : Check submesh for given shape: if all elements on this shape
+//purpose : Check sub-meshes of a given shape: if all elements on sub-shapes
// are quadratic, quadratic elements will be created.
-// Also fill myTLinkNodeMap
+// Fill myTLinkNodeMap
//=======================================================================
bool SMESH_MesherHelper::IsQuadraticSubMesh(const TopoDS_Shape& aSh)
SMESHDS_Mesh* meshDS = GetMeshDS();
// we can create quadratic elements only if all elements
// created on sub-shapes of given shape are quadratic
- // also we have to fill myTLinkNodeMap
myCreateQuadratic = true;
mySeamShapeIds.clear();
myDegenShapeIds.clear();
}
SMDSAbs_ElementType elemType( subType==TopAbs_FACE ? SMDSAbs_Face : SMDSAbs_Edge );
-
- //int nbOldLinks = myTLinkNodeMap.size();
-
if ( !myMesh->HasShapeToMesh() )
{
if (( myCreateQuadratic = myMesh->NbFaces( ORDER_QUADRATIC )))
}
}
+//=======================================================================
+/*!
+ * \brief Copy shape information from another helper. Used to improve performance
+ * since SetSubShape() can be time consuming if there are many edges
+ */
+//=======================================================================
+
+void SMESH_MesherHelper::CopySubShapeInfo(const SMESH_MesherHelper& other)
+{
+ this->myShape = other.myShape;
+ this->myShapeID = other.myShapeID;
+ this->myDegenShapeIds = other.myDegenShapeIds;
+ this->mySeamShapeIds = other.mySeamShapeIds;
+ this->myPar1[0] = other.myPar1[0];
+ this->myPar1[1] = other.myPar1[1];
+ this->myPar2[0] = other.myPar2[0];
+ this->myPar2[1] = other.myPar2[1];
+ this->myParIndex = other.myParIndex;
+ this->myFace2Surface = other.myFace2Surface;
+}
+
//=======================================================================
//function : ShapeToIndex
//purpose : Convert a shape to its index in the SMESHDS_Mesh
//purpose : Return true if 2D mesh on FACE is ditorted
//=======================================================================
-bool SMESH_MesherHelper::IsDistorted2D( SMESH_subMesh* faceSM,
- bool checkUV)
+bool SMESH_MesherHelper::IsDistorted2D( SMESH_subMesh* faceSM,
+ bool checkUV,
+ SMESH_MesherHelper* faceHelper)
{
if ( !faceSM || faceSM->GetSubShape().ShapeType() != TopAbs_FACE )
return false;
bool haveBadFaces = false;
SMESH_MesherHelper helper( *faceSM->GetFather() );
+ if ( faceHelper )
+ helper.CopySubShapeInfo( *faceHelper );
helper.SetSubShape( faceSM->GetSubShape() );
const TopoDS_Face& F = TopoDS::Face( faceSM->GetSubShape() );
SMESHDS_SubMesh* smDS = helper.GetMeshDS()->MeshElements( F );
if ( !smDS || smDS->NbElements() == 0 ) return false;
+ bool subIdsValid = true; // shape ID of nodes is OK
+ if ( helper.HasSeam() )
+ {
+ // check if nodes are bound to seam edges
+ SMESH_subMeshIteratorPtr smIt = faceSM->getDependsOnIterator(/*includeSelf=*/false);
+ while ( smIt->more() && subIdsValid )
+ {
+ SMESH_subMesh* sm = smIt->next();
+ if ( helper.IsSeamShape( sm->GetId() ) && sm->IsEmpty() )
+ subIdsValid = false;
+ }
+ }
SMDS_ElemIteratorPtr faceIt = smDS->GetElements();
double prevArea = 0;
vector< const SMDS_MeshNode* > nodes;
if ( isOnDegen )
continue;
}
- // prepare to getting UVs
+ // prepare for getting UVs
const SMDS_MeshNode* inFaceNode = 0;
if ( helper.HasSeam() ) {
for ( size_t i = 0; ( i < nodes.size() && !inFaceNode ); ++i )
if ( !helper.IsSeamShape( nodes[ i ]->getshapeId() ))
+ {
inFaceNode = nodes[ i ];
+ if ( !subIdsValid )
+ {
+ gp_XY uv = helper.GetNodeUV( F, inFaceNode );
+ if ( helper.IsOnSeam( uv ))
+ inFaceNode = NULL;
+ }
+ }
if ( !inFaceNode )
continue;
}
for ( size_t i = 0; i < nodes.size(); ++i )
uv[ i ] = helper.GetNodeUV( F, nodes[ i ], inFaceNode, toCheckUV );
+ if ( !subIdsValid ) // fix uv on seam
+ {
+ gp_XY uvInFace = helper.GetNodeUV( F, inFaceNode );
+ for ( size_t i = 0; i < uv.size(); ++i )
+ if ( helper.IsOnSeam( uv[i] ))
+ uv[i] = helper.getUVOnSeam( uv[i], uvInFace ).XY();
+ }
+
// compare orientation of triangles
double faceArea = 0;
for ( int iT = 0, nbT = nodes.size()-2; iT < nbT; ++iT )
//=======================================================================
//function : IsSubShape
-//purpose :
+//purpose :
//=======================================================================
bool SMESH_MesherHelper::IsSubShape( const TopoDS_Shape& shape,
return fabs(param-myPar1[i]) < fabs(param-myPar2[i]) ? myPar2[i] : myPar1[i];
}
+//=======================================================================
+//function : IsOnSeam
+//purpose : Check if UV is on seam. Return 0 if not, 1 for U seam, 2 for V seam
+//=======================================================================
+
+int SMESH_MesherHelper::IsOnSeam(const gp_XY& uv) const
+{
+ for ( int i = U_periodic; i <= V_periodic ; ++i )
+ if ( myParIndex & i )
+ {
+ double p = uv.Coord( i );
+ double tol = ( myPar2[i-1] - myPar1[i-1] ) / 100.;
+ if ( Abs( p - myPar1[i-1] ) < tol ||
+ Abs( p - myPar2[i-1] ) < tol )
+ return i;
+ }
+ return 0;
+}
+
namespace {
//=======================================================================
/*!
* \brief Return true if 2D mesh on FACE is distored
*/
- static bool IsDistorted2D( SMESH_subMesh* faceSM, bool checkUV=false );
+ static bool IsDistorted2D( SMESH_subMesh* faceSM,
+ bool checkUV = false,
+ SMESH_MesherHelper* faceHelper = NULL);
/*!
* \brief Returns true if given node is medium
* \brief Return the shape set by IsQuadraticSubMesh() or SetSubShape()
*/
const TopoDS_Shape& GetSubShape() const { return myShape; }
+ /*!
+ * \brief Copy shape information from another helper to improve performance
+ * since SetSubShape() can be time consuming if there are many edges
+ */
+ void CopySubShapeInfo(const SMESH_MesherHelper& other);
+
/*!
* \brief Convert a shape to its index in the SMESHDS_Mesh
* \brief Return an alternative parameter for a node on seam
*/
double GetOtherParam(const double param) const;
+ /*!
+ * \brief Check if UV is on seam. Return 0 if not, 1 for U seam, 2 for V seam
+ */
+ int IsOnSeam(const gp_XY& uv) const;
/*!
* \brief Return existing or create new medium nodes between given ones
static void WriteShape(const TopoDS_Shape& s);
+
protected:
/*!
double getFaceMaxTol( const TopoDS_Shape& face ) const;
+
private:
// forbidden copy constructor
* \brief Constructor of a side of one edge
* \param theFace - the face
* \param theEdge - the edge
- */
+ */
//================================================================================
StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face& theFace,
SMESH_Mesh* theMesh,
const bool theIsForward,
const bool theIgnoreMediumNodes,
+ SMESH_MesherHelper* theFaceHelper,
SMESH_ProxyMesh::Ptr theProxyMesh)
{
std::list<TopoDS_Edge> edges(1,theEdge);
- *this = StdMeshers_FaceSide( theFace, edges, theMesh, theIsForward,
- theIgnoreMediumNodes, theProxyMesh );
+ StdMeshers_FaceSide tmp( theFace, edges, theMesh, theIsForward,
+ theIgnoreMediumNodes, theFaceHelper, theProxyMesh );
+ *this = tmp;
+
+ tmp.myHelper = NULL;
}
//================================================================================
SMESH_Mesh* theMesh,
const bool theIsForward,
const bool theIgnoreMediumNodes,
+ SMESH_MesherHelper* theFaceHelper,
SMESH_ProxyMesh::Ptr theProxyMesh)
{
int nbEdges = theEdges.size();
myMissingVertexNodes = false;
myIgnoreMediumNodes = theIgnoreMediumNodes;
myDefaultPnt2d = gp_Pnt2d( 1e+100, 1e+100 );
+ myHelper = NULL;
if ( !myProxyMesh ) myProxyMesh.reset( new SMESH_ProxyMesh( *theMesh ));
+ if ( theFaceHelper && theFaceHelper->GetSubShape() == myFace )
+ {
+ myHelper = new SMESH_MesherHelper( * myProxyMesh->GetMesh() );
+ myHelper->CopySubShapeInfo( *theFaceHelper );
+ }
if ( nbEdges == 0 ) return;
SMESHDS_Mesh* meshDS = myProxyMesh->GetMeshDS();
myLast.push_back ( theULast );
myNormPar.push_back ( 1. );
myIsUniform.push_back( true );
+ myHelper = NULL;
myLength = 0;
myProxyMesh = theSide->myProxyMesh;
myDefaultPnt2d = *thePnt2d1;
}
myFace = theFace;
+ myHelper = NULL;
myPoints = theSideNodes;
myNbPonits = myPoints.size();
myNbSegments = myNbPonits + 1;
myEdgeLength.resize( 1, myLength );
}
+//================================================================================
+/*!
+ * \brief Destructor
+ */
+//================================================================================
+
+StdMeshers_FaceSide::~StdMeshers_FaceSide()
+{
+ delete myHelper; myHelper = NULL;
+}
+
//================================================================================
/*
* Return info on nodes on the side
if ( NbEdges() == 0 ) return myPoints;
StdMeshers_FaceSide* me = const_cast< StdMeshers_FaceSide* >( this );
- SMESH_MesherHelper eHelper( *myProxyMesh->GetMesh() );
- SMESH_MesherHelper fHelper( *myProxyMesh->GetMesh() );
- fHelper.SetSubShape( myFace );
bool paramOK = true;
double eps = 1e-100;
+ SMESH_MesherHelper eHelper( *myProxyMesh->GetMesh() );
+ SMESH_MesherHelper& fHelper = *FaceHelper();
+
// sort nodes of all edges by putting them into a map
map< double, const SMDS_MeshNode*> u2node;
if ( NbEdges() == 0 ) return resultNodes;
//SMESHDS_Mesh* meshDS = myProxyMesh->GetMeshDS();
- SMESH_MesherHelper eHelper( *myProxyMesh->GetMesh() );
- SMESH_MesherHelper fHelper( *myProxyMesh->GetMesh() );
- fHelper.SetSubShape( myFace );
+ SMESH_MesherHelper eHelper( *myProxyMesh->GetMesh() );
+ SMESH_MesherHelper& fHelper = * FaceHelper();
bool paramOK = true;
// Sort nodes of all edges putting them into a map
}
}
- SMESH_MesherHelper helper( *myProxyMesh->GetMesh() );
- helper.SetSubShape( myFace );
+ SMESH_MesherHelper* helper = FaceHelper();
std::set< const SMDS_MeshNode* > vNodes;
const int nbV = NbEdges() + !IsClosed();
if ( const SMDS_MeshNode* n = VertexNode( i ))
{
if ( !vNodes.insert( n ).second &&
- ( helper.IsRealSeam ( n->getshapeId() ) ||
- helper.IsDegenShape( n->getshapeId() )))
+ ( helper->IsRealSeam ( n->getshapeId() ) ||
+ helper->IsDegenShape( n->getshapeId() )))
me->myNbPonits++;
}
else
SMESH_Mesh & theMesh,
const bool theIgnoreMediumNodes,
TError & theError,
+ SMESH_MesherHelper* theFaceHelper,
SMESH_ProxyMesh::Ptr theProxyMesh,
const bool theCheckVertexNodes)
{
+ SMESH_MesherHelper helper( theMesh );
+ if ( theFaceHelper && theFaceHelper->GetSubShape() == theFace )
+ helper.CopySubShapeInfo( *theFaceHelper );
+
list< TopoDS_Edge > edges, internalEdges;
list< int > nbEdgesInWires;
int nbWires = SMESH_Block::GetOrderedEdges (theFace, edges, nbEdgesInWires);
StdMeshers_FaceSide* wire = new StdMeshers_FaceSide( theFace, wireEdges, &theMesh,
/*isForward=*/true, theIgnoreMediumNodes,
- theProxyMesh );
+ &helper, theProxyMesh );
wires[ iW ] = StdMeshers_FaceSidePtr( wire );
from = to;
}
{
StdMeshers_FaceSide* wire = new StdMeshers_FaceSide( theFace, internalEdges.back(), &theMesh,
/*isForward=*/true, theIgnoreMediumNodes,
- theProxyMesh );
+ &helper, theProxyMesh );
wires.push_back( StdMeshers_FaceSidePtr( wire ));
internalEdges.pop_back();
}
{
return myEdge.empty() ? false : FirstVertex().IsSame( LastVertex() );
}
+
+//================================================================================
+/*!
+ * \brief Return a helper initialized with the FACE
+ */
+//================================================================================
+
+SMESH_MesherHelper* StdMeshers_FaceSide::FaceHelper() const
+{
+ StdMeshers_FaceSide* me = const_cast< StdMeshers_FaceSide* >( this );
+ if ( !myHelper && myProxyMesh )
+ {
+ me->myHelper = new SMESH_MesherHelper( *myProxyMesh->GetMesh() );
+ me->myHelper->SetSubShape( myFace );
+ }
+ return me->myHelper;
+}
#include <list>
#include <boost/shared_ptr.hpp>
-class SMDS_MeshNode;
-class SMESH_Mesh;
class Adaptor2d_Curve2d;
class Adaptor3d_Curve;
class BRepAdaptor_CompCurve;
-struct SMESH_ComputeError;
+class SMDS_MeshNode;
+class SMESH_Mesh;
+class SMESH_MesherHelper;
class StdMeshers_FaceSide;
+struct SMESH_ComputeError;
typedef boost::shared_ptr< SMESH_ComputeError > TError;
typedef boost::shared_ptr< StdMeshers_FaceSide > StdMeshers_FaceSidePtr;
class STDMESHERS_EXPORT StdMeshers_FaceSide
{
public:
+
+ enum { ALL_EDGES = -1, LAST_EDGE = -1 }; //!< constants
+
/*!
* \brief Wrap one edge
*/
SMESH_Mesh* theMesh,
const bool theIsForward,
const bool theIgnoreMediumNodes,
+ SMESH_MesherHelper* theFaceHelper = NULL,
SMESH_ProxyMesh::Ptr theProxyMesh = SMESH_ProxyMesh::Ptr());
/*!
* \brief Wrap several edges. Edges must be properly ordered and oriented.
SMESH_Mesh* theMesh,
const bool theIsForward,
const bool theIgnoreMediumNodes,
+ SMESH_MesherHelper* theFaceHelper = NULL,
SMESH_ProxyMesh::Ptr theProxyMesh = SMESH_ProxyMesh::Ptr());
/*!
* \brief Simulate a side from a vertex using data from other FaceSide
StdMeshers_FaceSide(const StdMeshers_FaceSide* theSide,
const SMDS_MeshNode* theNode,
const gp_Pnt2d* thePnt2d1,
- const gp_Pnt2d* thePnt2d2=NULL,
- const Handle(Geom2d_Curve)& theC2d=NULL,
- const double theUFirst=0.,
- const double theULast=1.);
+ const gp_Pnt2d* thePnt2d2 = NULL,
+ const Handle(Geom2d_Curve)& theC2d = NULL,
+ const double theUFirst = 0.,
+ const double theULast = 1.);
/*!
* \brief Create a side from an UVPtStructVec
*/
const TopoDS_Edge& theEdge = TopoDS_Edge(),
SMESH_Mesh* theMesh = 0);
+ ~StdMeshers_FaceSide();
+
// static "consrtuctors"
static StdMeshers_FaceSidePtr New(const TopoDS_Face& Face,
const TopoDS_Edge& Edge,
SMESH_Mesh* Mesh,
const bool IsForward,
const bool IgnoreMediumNodes,
+ SMESH_MesherHelper* FaceHelper = NULL,
SMESH_ProxyMesh::Ptr ProxyMesh = SMESH_ProxyMesh::Ptr())
{ return StdMeshers_FaceSidePtr
- ( new StdMeshers_FaceSide( Face,Edge,Mesh,IsForward,IgnoreMediumNodes,ProxyMesh ));
+ ( new StdMeshers_FaceSide( Face,Edge,Mesh,IsForward,IgnoreMediumNodes,FaceHelper,ProxyMesh ));
}
static StdMeshers_FaceSidePtr New (const TopoDS_Face& Face,
std::list<TopoDS_Edge>& Edges,
SMESH_Mesh* Mesh,
const bool IsForward,
const bool IgnoreMediumNodes,
+ SMESH_MesherHelper* FaceHelper = NULL,
SMESH_ProxyMesh::Ptr ProxyMesh = SMESH_ProxyMesh::Ptr())
{ return StdMeshers_FaceSidePtr
- ( new StdMeshers_FaceSide( Face,Edges,Mesh,IsForward,IgnoreMediumNodes,ProxyMesh ));
+ ( new StdMeshers_FaceSide( Face,Edges,Mesh,IsForward,IgnoreMediumNodes,FaceHelper,ProxyMesh ));
}
static StdMeshers_FaceSidePtr New (const StdMeshers_FaceSide* Side,
const SMDS_MeshNode* Node,
const gp_Pnt2d* Pnt2d1,
- const gp_Pnt2d* Pnt2d2=NULL,
- const Handle(Geom2d_Curve)& C2d=NULL,
- const double UFirst=0.,
- const double ULast=1.)
+ const gp_Pnt2d* Pnt2d2 = NULL,
+ const Handle(Geom2d_Curve)& C2d = NULL,
+ const double UFirst = 0.,
+ const double ULast = 1.)
{ return StdMeshers_FaceSidePtr
( new StdMeshers_FaceSide( Side,Node,Pnt2d1,Pnt2d2,C2d,UFirst,ULast ));
}
SMESH_Mesh & theMesh,
const bool theIgnoreMediumNodes,
TError & theError,
+ SMESH_MesherHelper* theFaceHelper = NULL,
SMESH_ProxyMesh::Ptr theProxyMesh = SMESH_ProxyMesh::Ptr(),
- const bool theCheckVertexNodes=true);
+ const bool theCheckVertexNodes = true);
/*!
* \brief Change orientation of side geometry
*/
* Missing nodes are allowed only on internal vertices.
* For a closed side, the 1st point repeats at end
*/
- const UVPtStructVec& GetUVPtStruct(bool isXConst =0, double constValue =0) const;
+ const UVPtStructVec& GetUVPtStruct( bool isXConst = 0, double constValue = 0 ) const;
/*!
* \brief Simulates detailed data on nodes
* \param isXConst - true if normalized parameter X is constant
double constValue = 0) const;
/*!
* \brief Return nodes in the order they encounter while walking along
- * the while side or a specified EDGE.
- * For a closed side, the 1st point repeats at end
+ * the while side or a specified EDGE. For a closed side, the 1st point repeats at end.
+ * \param iE - index of the EDGE. Default is "all EDGEs".
*/
- std::vector<const SMDS_MeshNode*> GetOrderedNodes(int iE=-1) const;
+ std::vector<const SMDS_MeshNode*> GetOrderedNodes( int iE = ALL_EDGES ) const;
/*!
* \brief Return nodes of the i-th EDGE.
/*!
* \brief Return last vertex of the i-th edge (count starts from zero)
*/
- TopoDS_Vertex LastVertex(int i=-1) const;
+ TopoDS_Vertex LastVertex(int i = LAST_EDGE) const;
/*!
* \brief Return \c true if the chain of EDGEs is closed
*/
*/
inline int EdgeIndex( double U ) const;
- //virtual gp_Pnt Value(double U) const;
-
void dump(const char* msg=0) const;
/*!
* \brief Return orientation of i-th wrapped edge (count starts from zero)
*/
inline bool IsReversed(int i) const;
+ /*!
+ * \brief Return a helper initialized with the FACE
+ */
+ SMESH_MesherHelper* FaceHelper() const;
protected:
SMESH_ProxyMesh::Ptr myProxyMesh;
bool myMissingVertexNodes, myIgnoreMediumNodes;
gp_Pnt2d myDefaultPnt2d;
+ SMESH_MesherHelper* myHelper;
};
// get all edges of a face
TError problem;
TWireVector wires =
- StdMeshers_FaceSide::GetFaceWires( F, aMesh, skipMediumNodes, problem, proxyMesh );
+ StdMeshers_FaceSide::GetFaceWires( F, aMesh, skipMediumNodes, problem, _helper, proxyMesh );
int nbWires = wires.size();
if ( problem && !problem->IsOK() ) return error( problem );
if ( nbWires == 0 ) return error( "Problem in StdMeshers_FaceSide::GetFaceWires()");
if ( !proxyMesh )
return false;
- TError erorr;
+ TError err;
TSideVector wires = StdMeshers_FaceSide::GetFaceWires(face, theMesh,
/*skipMediumNodes=*/_quadraticMesh,
- erorr, proxyMesh,
+ err, &helper, proxyMesh,
/*checkVertexNodes=*/false);
if ( wires.size() != 1 )
return error( COMPERR_BAD_SHAPE, SMESH_Comment("One wire required, not ") << wires.size() );
"Non-quadrilateral faces are not opposite"));
// check that the found top and bottom FACEs are opposite
+ TopTools_IndexedMapOfShape topEdgesMap( thePrism.myBottomEdges.size() );
+ TopExp::MapShapes( thePrism.myTop, topEdgesMap );
list< TopoDS_Edge >::iterator edge = thePrism.myBottomEdges.begin();
for ( ; edge != thePrism.myBottomEdges.end(); ++edge )
- if ( myHelper->IsSubShape( *edge, thePrism.myTop ))
+ if ( topEdgesMap.Contains( *edge ))
return toSM( error
(notQuadGeomSubMesh.empty() ? COMPERR_BAD_INPUT_MESH : COMPERR_BAD_SHAPE,
"Non-quadrilateral faces are not opposite"));
}
TopoDS_Face F = TopoDS::Face( theShape );
TError err;
- TSideVector wires = StdMeshers_FaceSide::GetFaceWires( F, theMesh,
- /*ignoreMediumNodes=*/false, err);
+ TSideVector wires = StdMeshers_FaceSide::GetFaceWires( F, theMesh, /*ignoreMediumNodes=*/false,
+ err, &helper);
if ( err && !err->IsOK() )
return error( err );
const TopoDS_Face& srcFace,
SMESH_Mesh * tgtMesh,
SMESH_Mesh * srcMesh,
+ SMESH_MesherHelper* tgtHelper,
const TAssocTool::TShapeShapeMap& shape2ShapeMap,
TSideVector& srcWires,
TSideVector& tgtWires,
// get ordered src EDGEs
TError err;
- srcWires = StdMeshers_FaceSide::GetFaceWires( srcFace, *srcMesh,/*skipMediumNodes=*/0, err);
+ srcWires = StdMeshers_FaceSide::GetFaceWires( srcFace, *srcMesh,/*skipMediumNodes=*/0, err );
if (( err && !err->IsOK() ) ||
( srcWires.empty() ))
return err;
<< tgtMesh->GetMeshDS()->ShapeToIndex( tgtFace ) << " <- "
<< srcMesh->GetMeshDS()->ShapeToIndex( srcFace ) << endl;
#endif
- SMESH_MesherHelper srcHelper( *srcMesh );
- srcHelper.SetSubShape( srcFace );
// make corresponding sequence of tgt EDGEs
tgtWires.resize( srcWires.size() );
tgtWires[ iW ].reset( new StdMeshers_FaceSide( tgtFace, tgtEdges, tgtMesh,
/*theIsForward = */ true,
- /*theIgnoreMediumNodes = */false));
+ /*theIgnoreMediumNodes = */false,
+ tgtHelper ));
StdMeshers_FaceSidePtr tgtWire = tgtWires[ iW ];
// Fill map of src to tgt nodes with nodes on edges
else
{
const bool skipMedium = true, isFwd = true;
- StdMeshers_FaceSide srcEdge( srcFace, srcWire->Edge(iE), srcMesh, isFwd, skipMedium);
- StdMeshers_FaceSide tgtEdge( tgtFace, tgtWire->Edge(iE), tgtMesh, isFwd, skipMedium);
-
+ StdMeshers_FaceSide srcEdge( srcFace, srcWire->Edge(iE),
+ srcMesh, isFwd, skipMedium, srcWires[0]->FaceHelper() );
+ StdMeshers_FaceSide tgtEdge( tgtFace, tgtWire->Edge(iE),
+ tgtMesh, isFwd, skipMedium, tgtHelper);
+
vector< const SMDS_MeshNode* > srcNodes = srcEdge.GetOrderedNodes();
vector< const SMDS_MeshNode* > tgtNodes = tgtEdge.GetOrderedNodes();
TAssocTool::TNodeNodeMap& src2tgtNodes,
const bool is1DComputed)
{
- SMESH_Mesh * tgtMesh = tgtWires[0]->GetMesh();
- SMESH_Mesh * srcMesh = srcWires[0]->GetMesh();
- SMESHDS_Mesh* tgtMeshDS = tgtMesh->GetMeshDS();
- SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
- SMESH_MesherHelper helper( *tgtMesh );
+ SMESH_Mesh * tgtMesh = tgtWires[0]->GetMesh();
+ SMESH_Mesh * srcMesh = srcWires[0]->GetMesh();
+ SMESHDS_Mesh* tgtMeshDS = tgtMesh->GetMeshDS();
+ SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
+ SMESH_MesherHelper* helper = tgtWires[0]->FaceHelper();
const double tol = 1.e-7 * srcMeshDS->getMaxDim();
0.123 * ( srcSurf.FirstVParameter() + srcSurf.LastVParameter() ));
gp_Pnt tgtTrsfP = trsf.Transform( srcP );
TopLoc_Location loc;
- GeomAPI_ProjectPointOnSurf& proj = helper.GetProjector( tgtFace, loc, 0.1*tol );
+ GeomAPI_ProjectPointOnSurf& proj = helper->GetProjector( tgtFace, loc, 0.1*tol );
if ( !loc.IsIdentity() )
tgtTrsfP.Transform( loc.Transformation().Inverted() );
proj.Perform( tgtTrsfP );
// Make new faces
// prepare the helper to adding quadratic elements if necessary
- //helper.SetSubShape( tgtFace );
- helper.IsQuadraticSubMesh( tgtFace );
+ helper->IsQuadraticSubMesh( tgtFace );
SMESHDS_SubMesh* srcSubDS = srcMeshDS->MeshElements( srcFace );
if ( !is1DComputed && srcSubDS->NbElements() )
- helper.SetIsQuadratic( srcSubDS->GetElements()->next()->IsQuadratic() );
+ helper->SetIsQuadratic( srcSubDS->GetElements()->next()->IsQuadratic() );
- SMESH_MesherHelper srcHelper( *srcMesh );
- srcHelper.SetSubShape( srcFace );
- SMESH_MesherHelper edgeHelper( *tgtMesh );
+ SMESH_MesherHelper* srcHelper = srcWires[0]->FaceHelper();
+ SMESH_MesherHelper edgeHelper( *tgtMesh );
edgeHelper.ToFixNodeParameters( true );
const SMDS_MeshNode* nullNode = 0;
const SMDS_MeshElement* elem = elemIt->next();
const int nbN = elem->NbCornerNodes();
tgtNodes.resize( nbN );
- helper.SetElementsOnShape( false );
+ helper->SetElementsOnShape( false );
for ( int i = 0; i < nbN; ++i ) // loop on nodes of the source element
{
const SMDS_MeshNode* srcNode = elem->GetNode(i);
{
// create a new node
gp_Pnt tgtP = trsf.Transform( SMESH_TNodeXYZ( srcNode ));
- SMDS_MeshNode* n = helper.AddNode( tgtP.X(), tgtP.Y(), tgtP.Z() );
+ SMDS_MeshNode* n = helper->AddNode( tgtP.X(), tgtP.Y(), tgtP.Z() );
srcN_tgtN->second = n;
switch ( srcNode->GetPosition()->GetTypeOfPosition() )
{
case SMDS_TOP_FACE:
{
- gp_Pnt2d srcUV = srcHelper.GetNodeUV( srcFace, srcNode );
- tgtMeshDS->SetNodeOnFace( n, helper.GetSubShapeID(), srcUV.X(), srcUV.Y() );
+ gp_Pnt2d srcUV = srcHelper->GetNodeUV( srcFace, srcNode );
+ tgtMeshDS->SetNodeOnFace( n, helper->GetSubShapeID(), srcUV.X(), srcUV.Y() );
break;
}
case SMDS_TOP_EDGE:
{
const TopoDS_Edge& srcE = TopoDS::Edge( srcMeshDS->IndexToShape( srcNode->getshapeId()));
const TopoDS_Edge& tgtE = TopoDS::Edge( shape2ShapeMap( srcE, /*isSrc=*/true ));
- double srcU = srcHelper.GetNodeU( srcE, srcNode );
+ double srcU = srcHelper->GetNodeU( srcE, srcNode );
tgtMeshDS->SetNodeOnEdge( n, tgtE, srcU );
if ( !tgtFace.IsPartner( srcFace ))
{
tgtNodes[i] = srcN_tgtN->second;
}
// create a new face
- helper.SetElementsOnShape( true );
+ helper->SetElementsOnShape( true );
switch ( nbN )
{
- case 3: helper.AddFace(tgtNodes[0], tgtNodes[tri1], tgtNodes[tri2]); break;
- case 4: helper.AddFace(tgtNodes[0], tgtNodes[quad1], tgtNodes[2], tgtNodes[quad3]); break;
+ case 3: helper->AddFace(tgtNodes[0], tgtNodes[tri1], tgtNodes[tri2]); break;
+ case 4: helper->AddFace(tgtNodes[0], tgtNodes[quad1], tgtNodes[2], tgtNodes[quad3]); break;
default:
if ( isReverse ) std::reverse( tgtNodes.begin(), tgtNodes.end() );
- helper.AddPolygonalFace( tgtNodes );
+ helper->AddPolygonalFace( tgtNodes );
}
}
if ( !tgtFace.IsPartner( srcFace ) )
{
- helper.ToFixNodeParameters( true );
+ helper->ToFixNodeParameters( true );
int nbOkPos = 0;
const double tol2d = 1e-12;
case SMDS_TOP_FACE:
{
if ( nbOkPos > 10 ) break;
- gp_XY uv = helper.GetNodeUV( tgtFace, n ), uvBis = uv;
- if (( helper.CheckNodeUV( tgtFace, n, uv, tol )) &&
+ gp_XY uv = helper->GetNodeUV( tgtFace, n ), uvBis = uv;
+ if (( helper->CheckNodeUV( tgtFace, n, uv, tol )) &&
(( uv - uvBis ).SquareModulus() < tol2d ))
++nbOkPos;
else
SMESHDS_SubMesh* srcSubDS = srcMesh->GetMeshDS()->MeshElements( srcFace );
- SMESH_MesherHelper helper( *tgtMesh );
- helper.SetSubShape( tgtFace );
+ SMESH_MesherHelper* helper = tgtWires[0]->FaceHelper();
if ( is1DComputed )
- helper.IsQuadraticSubMesh( tgtFace );
+ helper->IsQuadraticSubMesh( tgtFace );
else
- helper.SetIsQuadratic( srcSubDS->GetElements()->next()->IsQuadratic() );
- helper.SetElementsOnShape( true );
+ helper->SetIsQuadratic( srcSubDS->GetElements()->next()->IsQuadratic() );
+ helper->SetElementsOnShape( true );
Handle(Geom_Surface) tgtSurface = BRep_Tool::Surface( tgtFace );
SMESHDS_Mesh* tgtMeshDS = tgtMesh->GetMeshDS();
- SMESH_MesherHelper srcHelper( *srcMesh );
- srcHelper.SetSubShape( srcFace );
+ SMESH_MesherHelper* srcHelper = srcWires[0]->FaceHelper();
const SMDS_MeshNode* nullNode = 0;
TAssocTool::TNodeNodeMap::iterator srcN_tgtN;
while ( elemIt->more() ) // loop on all mesh faces on srcFace
{
const SMDS_MeshElement* elem = elemIt->next();
- const int nbN = elem->NbCornerNodes();
+ const int nbN = elem->NbCornerNodes();
tgtNodes.resize( nbN );
for ( int i = 0; i < nbN; ++i ) // loop on nodes of the source element
{
if ( srcN_tgtN->second == nullNode )
{
// create a new node
- gp_Pnt2d srcUV = srcHelper.GetNodeUV( srcFace, srcNode,
- elem->GetNode( helper.WrapIndex(i+1,nbN)), &uvOK);
+ gp_Pnt2d srcUV = srcHelper->GetNodeUV( srcFace, srcNode,
+ elem->GetNode( helper->WrapIndex(i+1,nbN)), &uvOK);
gp_Pnt2d tgtUV = trsf.Transform( srcUV );
gp_Pnt tgtP = tgtSurface->Value( tgtUV.X(), tgtUV.Y() );
SMDS_MeshNode* n = tgtMeshDS->AddNode( tgtP.X(), tgtP.Y(), tgtP.Z() );
switch ( srcNode->GetPosition()->GetTypeOfPosition() )
{
case SMDS_TOP_FACE: {
- tgtMeshDS->SetNodeOnFace( n, helper.GetSubShapeID(), tgtUV.X(), tgtUV.Y() );
+ tgtMeshDS->SetNodeOnFace( n, helper->GetSubShapeID(), tgtUV.X(), tgtUV.Y() );
break;
}
case SMDS_TOP_EDGE: {
- TopoDS_Shape srcEdge = srcHelper.GetSubShapeByNode( srcNode, srcHelper.GetMeshDS() );
+ TopoDS_Shape srcEdge = srcHelper->GetSubShapeByNode( srcNode, srcHelper->GetMeshDS() );
TopoDS_Edge tgtEdge = TopoDS::Edge( shape2ShapeMap( srcEdge, /*isSrc=*/true ));
double U = Precision::Infinite();
- helper.CheckNodeU( tgtEdge, n, U, Precision::PConfusion());
+ helper->CheckNodeU( tgtEdge, n, U, Precision::PConfusion());
tgtMeshDS->SetNodeOnEdge( n, TopoDS::Edge( tgtEdge ), U );
break;
}
case SMDS_TOP_VERTEX: {
- TopoDS_Shape srcV = srcHelper.GetSubShapeByNode( srcNode, srcHelper.GetMeshDS() );
+ TopoDS_Shape srcV = srcHelper->GetSubShapeByNode( srcNode, srcHelper->GetMeshDS() );
TopoDS_Shape tgtV = shape2ShapeMap( srcV, /*isSrc=*/true );
tgtMeshDS->SetNodeOnVertex( n, TopoDS::Vertex( tgtV ));
break;
// create a new face (with reversed orientation)
switch ( nbN )
{
- case 3: helper.AddFace(tgtNodes[0], tgtNodes[2], tgtNodes[1]); break;
- case 4: helper.AddFace(tgtNodes[0], tgtNodes[3], tgtNodes[2], tgtNodes[1]); break;
+ case 3: helper->AddFace(tgtNodes[0], tgtNodes[2], tgtNodes[1]); break;
+ case 4: helper->AddFace(tgtNodes[0], tgtNodes[3], tgtNodes[2], tgtNodes[1]); break;
}
} // loop on all mesh faces on srcFace
// // as all XY are computed, create tgt nodes and faces
- // SMESH_MesherHelper helper( *tgtMesh );
- // helper.SetSubShape( tgtFace );
+ // SMESH_MesherHelper helper = *tgtWires[0]->FaceHelper();
// if ( is1DComputed )
// helper.IsQuadraticSubMesh( tgtFace );
// else
// helper.SetElementsOnShape( true );
// Handle(Geom_Surface) tgtSurface = BRep_Tool::Surface( tgtFace );
- // SMESH_MesherHelper srcHelper( *srcMesh );
- // srcHelper.SetSubShape( srcFace );
+ // SMESH_MesherHelper srcHelper = *srcWires[0]->FaceHelper();
// vector< const SMDS_MeshNode* > tgtNodes;
// gp_XY uv;
// get ordered src and tgt EDGEs
TSideVector srcWires, tgtWires;
bool is1DComputed = false; // if any tgt EDGE is meshed
- TError err = getWires( tgtFace, srcFace, tgtMesh, srcMesh,
+ TError err = getWires( tgtFace, srcFace, tgtMesh, srcMesh, &helper,
shape2ShapeMap, srcWires, tgtWires, _src2tgtNodes, is1DComputed );
if ( err && !err->IsOK() )
return error( err );
// boundary, also bad face can be created if EDGEs already discretized
// --> fix bad faces by smoothing
// ----------------------------------------------------------------
- if ( helper.IsDistorted2D( tgtSubMesh, /*checkUV=*/false ))
+ if ( helper.IsDistorted2D( tgtSubMesh, /*checkUV=*/false, &helper ))
{
morph( helper, tgtFace, srcFace, tgtWires, srcWires, _src2tgtNodes );
const SMESH_MAT2d::MedialAxis& theMA,
TMAPar2NPoints & thePointsOnE )
{
+ SMESH_Mesh* mesh = theHelper.GetMesh();
+ SMESHDS_Mesh* meshDS = theHelper.GetMeshDS();
+
list< TopoDS_Edge > ee1( theSinuFace._sinuSide [0].begin(), theSinuFace._sinuSide [0].end() );
list< TopoDS_Edge > ee2( theSinuFace._sinuSide [1].begin(), theSinuFace._sinuSide [1].end() );
- StdMeshers_FaceSide sideOut( theSinuFace.Face(), ee1, theHelper.GetMesh(), true, true );
- StdMeshers_FaceSide sideIn ( theSinuFace.Face(), ee2, theHelper.GetMesh(), true, true );
+ StdMeshers_FaceSide sideOut( theSinuFace.Face(), ee1, mesh, true, true, &theHelper );
+ StdMeshers_FaceSide sideIn ( theSinuFace.Face(), ee2, mesh, true, true, &theHelper );
const UVPtStructVec& uvsOut = sideOut.GetUVPtStruct();
const UVPtStructVec& uvsIn = sideIn.GetUVPtStruct();
// if ( uvs1.size() != uvs2.size() )
const SMESH_MAT2d::Branch& branch = *theMA.getBranch(0);
SMESH_MAT2d::BoundaryPoint bp[2];
SMESH_MAT2d::BranchPoint brp;
- SMESHDS_Mesh* meshDS = theHelper.GetMeshDS();
map< double, const SMDS_MeshNode* > nodeParams; // params of existing nodes
map< double, const SMDS_MeshNode* >::iterator u2n;
for ( int i = 0; i < 4; ++i )
{
theFace._quad->side[i] = StdMeshers_FaceSide::New( face, side[i], mesh, i < QUAD_TOP_SIDE,
- /*skipMediumNodes=*/true, proxyMesh );
+ /*skipMediumNodes=*/true,
+ &theHelper, proxyMesh );
}
if ( theFace.IsRing() )
continue;
StdMeshers_FaceSide side( face, theSinuEdges[i], mesh,
- /*isFwd=*/true, /*skipMediumNodes=*/true );
+ /*isFwd=*/true, /*skipMediumNodes=*/true, &theHelper );
vector<const SMDS_MeshNode*> nodes = side.GetOrderedNodes();
for ( size_t in = 1; in < nodes.size(); ++in )
{
myNeedSmooth = false;
myCheckOri = false;
- FaceQuadStruct::Ptr quad = CheckNbEdges( aMesh, F, /*considerMesh=*/true );
+ FaceQuadStruct::Ptr quad = CheckNbEdges( aMesh, F, /*considerMesh=*/true, myHelper );
if (!quad)
return false;
myQuadList.clear();
FaceQuadStruct::Ptr StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh & aMesh,
const TopoDS_Shape & aShape,
- const bool considerMesh)
+ const bool considerMesh,
+ SMESH_MesherHelper* aFaceHelper)
{
if ( !myQuadList.empty() && myQuadList.front()->face.IsSame( aShape ))
return myQuadList.front();
}
// find corner vertices of the quad
+ myHelper = ( aFaceHelper && aFaceHelper->GetSubShape() == aShape ) ? aFaceHelper : NULL;
vector<TopoDS_Vertex> corners;
int nbDegenEdges, nbSides = getCorners( F, aMesh, edges, corners, nbDegenEdges, considerMesh );
if ( nbSides == 0 )
sideEdges.push_back( *edgeIt++ );
if ( !sideEdges.empty() )
quad->side.push_back( StdMeshers_FaceSide::New(F, sideEdges, &aMesh, iSide < QUAD_TOP_SIDE,
- ignoreMediumNodes, myProxyMesh));
+ ignoreMediumNodes, myHelper, myProxyMesh));
else
--iSide;
}
{
quad->side.push_back
( StdMeshers_FaceSide::New( F, sideEdges, &aMesh, iSide < QUAD_TOP_SIDE,
- ignoreMediumNodes, myProxyMesh ));
+ ignoreMediumNodes, myHelper, myProxyMesh ));
++iSide;
}
if ( quad->side.size() == 4 )
{
TError err;
TSideVector wireVec =
- StdMeshers_FaceSide::GetFaceWires( geomFace, *myHelper->GetMesh(), true, err );
+ StdMeshers_FaceSide::GetFaceWires( geomFace, *myHelper->GetMesh(), true, err, myHelper );
StdMeshers_FaceSidePtr wire = wireVec[0];
// find a right angle VERTEX
theNbDegenEdges = 0;
SMESH_MesherHelper helper( theMesh );
- StdMeshers_FaceSide faceSide( theFace, theWire, &theMesh, /*isFwd=*/true, /*skipMedium=*/true);
+ if ( myHelper )
+ helper.CopySubShapeInfo( *myHelper );
+ StdMeshers_FaceSide faceSide( theFace, theWire, &theMesh,
+ /*isFwd=*/true, /*skipMedium=*/true, &helper );
// sort theVertices by angle
multimap<double, TopoDS_Vertex> vertexByAngle;
FaceQuadStruct::Ptr CheckNbEdges(SMESH_Mesh& aMesh,
const TopoDS_Shape& aShape,
- const bool considerMesh=false);
+ const bool considerMesh = false,
+ SMESH_MesherHelper* aFaceHelper = 0);
static bool IsApplicable(const TopoDS_Shape & aShape, bool toCheckAll);
SMESH_Mesh* aMesh,
StdMeshers_FaceSidePtr& aCircSide,
StdMeshers_FaceSidePtr& aLinSide1,
- StdMeshers_FaceSidePtr& aLinSide2)
+ StdMeshers_FaceSidePtr& aLinSide2,
+ SMESH_MesherHelper* helper)
{
const TopoDS_Face& face = TopoDS::Face( aShape );
aCircSide.reset(); aLinSide1.reset(); aLinSide2.reset();
StdMeshers_FaceSidePtr side;
if ( aMesh )
side = StdMeshers_FaceSide::New( face, sideEdges, aMesh,
- /*isFwd=*/true, /*skipMedium=*/ true );
+ /*isFwd=*/true, /*skipMedium=*/ true, helper );
sides.push_back( side );
}
edges.push_back( aCircSide->Edge( iE % aCircSide->NbEdges() ));
aCircSide = StdMeshers_FaceSide::New( face, edges, aMesh,
- /*isFwd=*/true, /*skipMedium=*/ true );
+ /*isFwd=*/true, /*skipMedium=*/ true, helper );
}
}
StdMeshers_Quadrangle_2D::myCheckOri = false;
StdMeshers_Quadrangle_2D::myQuadList.clear();
+ myHelper->SetSubShape( aShape );
+ myHelper->SetElementsOnShape( true );
+
StdMeshers_FaceSidePtr circSide, linSide1, linSide2;
- int nbSides = analyseFace( aShape, &aMesh, circSide, linSide1, linSide2 );
+ int nbSides = analyseFace( aShape, &aMesh, circSide, linSide1, linSide2, myHelper );
if( nbSides > 3 || nbSides < 1 )
return error("The face must be a full ellipse or a part of ellipse (i.e. the number "
"of edges is less or equal to 3 and one of them is an ellipse curve)");
Handle(Geom_Surface) S = BRep_Tool::Surface(F);
myHelper->IsQuadraticSubMesh( aShape );
- myHelper->SetElementsOnShape( true );
vector< double > layerPositions; // [0,1]
TopoDS_Edge linEdge = makeEdgeToCenter( circSide, F, circNode );
StdMeshers_FaceSidePtr tmpSide =
- StdMeshers_FaceSide::New( F, linEdge, &aMesh, /*isFrw=*/true, /*skipMedium=*/true );
+ StdMeshers_FaceSide::New( F, linEdge, &aMesh, /*isFrw=*/true, /*skipMedium=*/true, myHelper );
if ( !computeLayerPositions( tmpSide, layerPositions ))
return false;
isVIn0Shared = vIn0.IsSame( circSide->FirstVertex( iE ));
linSide1 = StdMeshers_FaceSide::New( F, edges, &aMesh,
- /*isFrw=*/isVIn0Shared, /*skipMedium=*/true );
+ /*isFrw=*/isVIn0Shared, /*skipMedium=*/true, myHelper );
int nbMeshedEdges;
if ( !computeLayerPositions( linSide1, layerPositions, &nbMeshedEdges ))
TNodeDistributor* algo1d = TNodeDistributor::GetDistributor(aMesh);
StdMeshers_FaceSidePtr circSide, linSide1, linSide2;
- int nbSides = analyseFace( aShape, &aMesh, circSide, linSide1, linSide2 );
+ int nbSides = analyseFace( aShape, &aMesh, circSide, linSide1, linSide2, myHelper );
if( nbSides > 3 || nbSides < 1 )
return false;
TopoDS_Edge linEdge = makeEdgeToCenter( circSide, F, circNode );
StdMeshers_FaceSidePtr tmpSide =
- StdMeshers_FaceSide::New( F, linEdge, &aMesh, /*isFrw=*/true, /*skipMedium=*/true );
+ StdMeshers_FaceSide::New( F, linEdge, &aMesh, /*isFrw=*/true, /*skipMedium=*/true, myHelper );
if ( !computeLayerPositions( tmpSide, layerPositions ))
return false;
for (TopExp_Explorer exp( aShape, TopAbs_FACE ); exp.More(); exp.Next(), ++nbFoundFaces )
{
StdMeshers_FaceSidePtr circSide, linSide1, linSide2;
- int nbSides = analyseFace( exp.Current(), NULL, circSide, linSide1, linSide2 );
+ int nbSides = analyseFace( exp.Current(), NULL, circSide, linSide1, linSide2, NULL );
bool ok = ( 0 < nbSides && nbSides <= 3 &&
isCornerInsideCircle( circSide, linSide1, linSide2 ));
if( toCheckAll && !ok ) return false;
VISCOUS_2D::_ViscousBuilder2D builder( theMesh, face, hyps, hypShapes );
builder._faceSideVec =
StdMeshers_FaceSide::GetFaceWires( face, theMesh, true, error,
- SMESH_ProxyMesh::Ptr(),
+ NULL, SMESH_ProxyMesh::Ptr(),
/*theCheckVertexNodes=*/false);
if ( error->IsOK() && !builder.findEdgesWithLayers())
{
SMESH_ProxyMesh::Ptr _ViscousBuilder2D::Compute()
{
- _faceSideVec = StdMeshers_FaceSide::GetFaceWires( _face, *_mesh, true, _error);
+ _faceSideVec = StdMeshers_FaceSide::GetFaceWires( _face, *_mesh, true, _error, &_helper );
if ( !_error->IsOK() )
return _proxyMesh;