#include "SMDS_EdgePosition.hxx"
#include "SMDS_VolumeTool.hxx"
#include "SMESH_subMesh.hxx"
+#include "SMESH_ProxyMesh.hxx"
#include <BRepAdaptor_Surface.hxx>
#include <BRepTools.hxx>
//=======================================================================
TopoDS_Shape SMESH_MesherHelper::GetSubShapeByNode(const SMDS_MeshNode* node,
- SMESHDS_Mesh* meshDS)
+ const SMESHDS_Mesh* meshDS)
{
int shapeID = node->getshapeId();
if ( 0 < shapeID && shapeID <= meshDS->MaxShapeIndex() )
const SMDS_MeshNode* n,
gp_XY& uv,
const double tol,
- const bool force) const
+ const bool force,
+ double distXYZ[4]) const
{
int shapeID = n->getshapeId();
if ( force || toCheckPosOnShape( shapeID ))
// check that uv is correct
TopLoc_Location loc;
Handle(Geom_Surface) surface = BRep_Tool::Surface( F,loc );
- gp_Pnt nodePnt = XYZ( n );
+ gp_Pnt nodePnt = XYZ( n ), surfPnt(0,0,0);
+ double dist = 0;
if ( !loc.IsIdentity() ) nodePnt.Transform( loc.Transformation().Inverted() );
- if ( Precision::IsInfinite( uv.X() ) ||
- Precision::IsInfinite( uv.Y() ) ||
- nodePnt.Distance( surface->Value( uv.X(), uv.Y() )) > toldis )
+ bool infinit = ( Precision::IsInfinite( uv.X() ) || Precision::IsInfinite( uv.Y() ));
+ if ( infinit ||
+ (dist = nodePnt.Distance( surfPnt = surface->Value( uv.X(), uv.Y() ))) > tol )
{
setPosOnShapeValidity( shapeID, false );
+ if ( !infinit && distXYZ ) {
+ surfPnt.Transform( loc );
+ distXYZ[0] = dist;
+ distXYZ[1] = surfPnt.X(); distXYZ[2] = surfPnt.Y(); distXYZ[3]=surfPnt.Z();
+ }
// uv incorrect, project the node to surface
GeomAPI_ProjectPointOnSurf& projector = GetProjector( F, loc, tol );
projector.Perform( nodePnt );
Quantity_Parameter U,V;
projector.LowerDistanceParameters(U,V);
uv.SetCoord( U,V );
- if ( nodePnt.Distance( surface->Value( U, V )) > toldis )
+ surfPnt = surface->Value( U, V );
+ dist = nodePnt.Distance( surfPnt );
+ if ( distXYZ ) {
+ surfPnt.Transform( loc );
+ distXYZ[0] = dist;
+ distXYZ[1] = surfPnt.X(); distXYZ[2] = surfPnt.Y(); distXYZ[3]=surfPnt.Z();
+ }
+ if ( dist > tol )
{
MESSAGE( "SMESH_MesherHelper::CheckNodeUV(), invalid projection" );
return false;
double& u,
const double tol,
const bool force,
- double* distance) const
+ double distXYZ[4]) const
{
int shapeID = n->getshapeId();
if ( force || toCheckPosOnShape( shapeID ))
{
- double toldis = tol;
- double tolmin = 1.e-7*myMesh->GetMeshDS()->getMaxDim(); // nodes coordinates are stored in float format
- if (toldis < tolmin) toldis = tolmin;
+ //double toldis = tol;
+ //double tolmin = 1.e-7*myMesh->GetMeshDS()->getMaxDim(); // nodes coordinates are stored in float format
+ //if (toldis < tolmin) toldis = tolmin;
// check that u is correct
TopLoc_Location loc; double f,l;
Handle(Geom_Curve) curve = BRep_Tool::Curve( E,loc,f,l );
{
gp_Pnt nodePnt = SMESH_MeshEditor::TNodeXYZ( n );
if ( !loc.IsIdentity() ) nodePnt.Transform( loc.Transformation().Inverted() );
- double dist = nodePnt.Distance( curve->Value( u ));
- if ( distance ) *distance = dist;
- if ( dist > toldis )
+ gp_Pnt curvPnt = curve->Value( u );
+ double dist = nodePnt.Distance( curvPnt );
+ if ( distXYZ ) {
+ curvPnt.Transform( loc );
+ distXYZ[0] = dist;
+ distXYZ[1] = curvPnt.X(); distXYZ[2] = curvPnt.Y(); distXYZ[3]=curvPnt.Z();
+ }
+ if ( dist > tol /*toldis*/ )
{
setPosOnShapeValidity( shapeID, false );
// u incorrect, project the node to the curve
}
Quantity_Parameter U = projector->LowerDistanceParameter();
u = double( U );
- dist = nodePnt.Distance( curve->Value( U ));
- if ( distance ) *distance = dist;
- if ( dist > toldis )
+ curvPnt = curve->Value( u );
+ dist = nodePnt.Distance( curvPnt );
+ if ( distXYZ ) {
+ curvPnt.Transform( loc );
+ distXYZ[0] = dist;
+ distXYZ[1] = curvPnt.X(); distXYZ[2] = curvPnt.Y(); distXYZ[3]=curvPnt.Z();
+ }
+ if ( dist > tol /*toldis*/)
{
MESSAGE( "SMESH_MesherHelper::CheckNodeU(), invalid projection" );
- MESSAGE("distance " << nodePnt.Distance(curve->Value( U )) << " " << toldis);
+ MESSAGE("distance " << dist << " " << tol/*dis*/);
return false;
}
// store the fixed U on the edge
// To find position on edge and 3D position for n12,
// project <middle> to 2 edges and select projection most close to <middle>
- double u = 0, distMiddleProj = Precision::Infinite();
+ double u = 0, distMiddleProj = Precision::Infinite(), distXYZ[4];
int iOkEdge = 0;
TopoDS_Edge edges[2];
for ( int is2nd = 0; is2nd < 2; ++is2nd )
// project to get U of projection and distance from middle to projection
TopoDS_Edge edge = edges[ is2nd ] = TopoDS::Edge( shape );
double node2MiddleDist = middle.Distance( XYZ(n) );
- double foundU = GetNodeU( edge, n ), foundDist = node2MiddleDist;
- CheckNodeU( edge, n12, foundU, 2*BRep_Tool::Tolerance(edge), /*force=*/true, &foundDist );
- if ( foundDist < node2MiddleDist )
+ double foundU = GetNodeU( edge, n );
+ CheckNodeU( edge, n12, foundU, 2*BRep_Tool::Tolerance(edge), /*force=*/true, distXYZ );
+ if ( distXYZ[0] < node2MiddleDist )
{
- distMiddleProj = foundDist;
+ distMiddleProj = distXYZ[0];
u = foundU;
iOkEdge = is2nd;
}
bool SMESH_MesherHelper::LoadNodeColumns(TParam2ColumnMap & theParam2ColumnMap,
const TopoDS_Face& theFace,
const TopoDS_Edge& theBaseEdge,
- SMESHDS_Mesh* theMesh)
+ SMESHDS_Mesh* theMesh,
+ SMESH_ProxyMesh* theProxyMesh)
{
- SMESHDS_SubMesh* faceSubMesh = theMesh->MeshElements( theFace );
+ const SMESHDS_SubMesh* faceSubMesh = 0;
+ if ( theProxyMesh )
+ {
+ faceSubMesh = theProxyMesh->GetSubMesh( theFace );
+ if ( !faceSubMesh ||
+ faceSubMesh->NbElements() == 0 ||
+ theProxyMesh->IsTemporary( faceSubMesh->GetElements()->next() ))
+ {
+ // can use a proxy sub-mesh with not temporary elements only
+ faceSubMesh = 0;
+ theProxyMesh = 0;
+ }
+ }
+ if ( !faceSubMesh )
+ faceSubMesh = theMesh->MeshElements( theFace );
if ( !faceSubMesh || faceSubMesh->NbElements() == 0 )
return false;
nCol.resize( nbRows );
nCol[0] = u_n->second;
}
+ TParam2ColumnMap::iterator par_nVec_2, par_nVec_1 = theParam2ColumnMap.begin();
+ if ( theProxyMesh )
+ {
+ for ( ; par_nVec_1 != theParam2ColumnMap.end(); ++par_nVec_1 )
+ {
+ const SMDS_MeshNode* & n = par_nVec_1->second[0];
+ n = theProxyMesh->GetProxyNode( n );
+ }
+ }
// fill theParam2ColumnMap column by column by passing from nodes on
// theBaseEdge up via mesh faces on theFace
- TParam2ColumnMap::iterator par_nVec_2 = theParam2ColumnMap.begin();
- TParam2ColumnMap::iterator par_nVec_1 = par_nVec_2++;
+ par_nVec_2 = theParam2ColumnMap.begin();
+ par_nVec_1 = par_nVec_2++;
TIDSortedElemSet emptySet, avoidSet;
for ( ; par_nVec_2 != theParam2ColumnMap.end(); ++par_nVec_1, ++par_nVec_2 )
{
if ( iRow + 1 < nbRows ) // compact if necessary
nCol1.resize( iRow + 1 ), nCol2.resize( iRow + 1 );
}
- return true;
+ return theParam2ColumnMap.size() > 1 && theParam2ColumnMap.begin()->second.size() > 1;
}
//=======================================================================
return tol;
}
+//================================================================================
+/*!
+ * \brief Check if the first and last vertices of an edge are the same
+ * \param anEdge - the edge to check
+ * \retval bool - true if same
+ */
+//================================================================================
+
+bool SMESH_MesherHelper::IsClosedEdge( const TopoDS_Edge& anEdge )
+{
+ if ( anEdge.Orientation() >= TopAbs_INTERNAL )
+ return IsClosedEdge( TopoDS::Edge( anEdge.Oriented( TopAbs_FORWARD )));
+ return TopExp::FirstVertex( anEdge ).IsSame( TopExp::LastVertex( anEdge ));
+}
+
//=======================================================================
//function : IsQuadraticMesh
//purpose : Check mesh without geometry for: if all elements on this shape are quadratic,
{
TopTools_ListIteratorOfListOfShape _ancIter;
TopAbs_ShapeEnum _type;
+ TopTools_MapOfShape _encountered;
TAncestorsIterator( const TopTools_ListOfShape& ancestors, TopAbs_ShapeEnum type)
: _ancIter( ancestors ), _type( type )
{
- if ( _ancIter.More() && _ancIter.Value().ShapeType() != _type ) next();
+ if ( _ancIter.More() ) {
+ if ( _ancIter.Value().ShapeType() != _type ) next();
+ else _encountered.Add( _ancIter.Value() );
+ }
}
virtual bool more()
{
const TopoDS_Shape* s = _ancIter.More() ? & _ancIter.Value() : 0;
if ( _ancIter.More() )
for ( _ancIter.Next(); _ancIter.More(); _ancIter.Next())
- if ( _ancIter.Value().ShapeType() == _type )
+ if ( _ancIter.Value().ShapeType() == _type && _encountered.Add( _ancIter.Value() ))
break;
return s;
}
class GeomAPI_ProjectPointOnSurf;
class GeomAPI_ProjectPointOnCurve;
+class SMESH_ProxyMesh;
typedef std::map<SMESH_TLink, const SMDS_MeshNode*> TLinkNodeMap;
typedef std::map<SMESH_TLink, const SMDS_MeshNode*>::iterator ItTLinkNode;
static bool LoadNodeColumns(TParam2ColumnMap & theParam2ColumnMap,
const TopoDS_Face& theFace,
const TopoDS_Edge& theBaseEdge,
- SMESHDS_Mesh* theMesh);
+ SMESHDS_Mesh* theMesh,
+ SMESH_ProxyMesh* theProxyMesh=0);
/*!
* \brief Return support shape of a node
* \param node - the node
* \retval TopoDS_Shape - found support shape
*/
static TopoDS_Shape GetSubShapeByNode(const SMDS_MeshNode* node,
- SMESHDS_Mesh* meshDS);
+ const SMESHDS_Mesh* meshDS);
/*!
* \brief Return a valid node index, fixing the given one if necessary
static double MaxTolerance( const TopoDS_Shape& shape );
+ static bool IsClosedEdge( const TopoDS_Edge& anEdge );
+
public:
// ---------- PUBLIC INSTANCE METHODS ----------
/*!
* \brief Check and fix node UV on a face
* \param force - check even if checks of other nodes on this face passed OK
+ * \param distXYZ - returns result distance and point coordinates
* \retval bool - false if UV is bad and could not be fixed
*/
bool CheckNodeUV(const TopoDS_Face& F,
const SMDS_MeshNode* n,
gp_XY& uv,
const double tol,
- const bool force=false) const;
+ const bool force=false,
+ double distXYZ[4]=0) const;
/*!
* \brief Check and fix node U on an edge
* \param force - check even if checks of other nodes on this edge passed OK
+ * \param distXYZ - returns result distance and point coordinates
* \retval bool - false if U is bad and could not be fixed
*/
bool CheckNodeU(const TopoDS_Edge& E,
double& u,
const double tol,
const bool force=false,
- double* distance=0) const;
+ double distXYZ[4]=0) const;
/*!
* \brief Return middle UV taking in account surface period
*/