X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FStdMeshers%2FStdMeshers_Cartesian_3D.cxx;h=6b0c68b93facfbd1f13490635d7730d58eefbac3;hb=2c8f4c513e0fed76a7f0331542e520e315740aa4;hp=9b8e47c9b2a1b246e4e8c48d43dd3c71ee44ced1;hpb=16042a875095298c5f1b414fd54e35228be36739;p=modules%2Fsmesh.git diff --git a/src/StdMeshers/StdMeshers_Cartesian_3D.cxx b/src/StdMeshers/StdMeshers_Cartesian_3D.cxx index 9b8e47c9b..6b0c68b93 100644 --- a/src/StdMeshers/StdMeshers_Cartesian_3D.cxx +++ b/src/StdMeshers/StdMeshers_Cartesian_3D.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS @@ -35,6 +35,7 @@ #include "utilities.h" #include "Utils_ExceptHandlers.hxx" +#include #include #include @@ -85,6 +86,17 @@ using namespace std; //#define _MY_DEBUG_ +#if OCC_VERSION_LARGE <= 0x06050300 +// workaround it required only for OCCT6.5.3 and older (see OCC22809) +#define ELLIPSOLID_WORKAROUND +#endif + +#ifdef ELLIPSOLID_WORKAROUND +#include +#include +#include +#endif + //============================================================================= /*! * Constructor @@ -246,6 +258,41 @@ namespace const TopoDS_Shape& shape ); void ComputeNodes(SMESH_MesherHelper& helper); }; +#ifdef ELLIPSOLID_WORKAROUND + // -------------------------------------------------------------------------- + /*! + * \brief struct temporary replacing IntCurvesFace_Intersector until + * OCCT bug 0022809 is fixed + * http://tracker.dev.opencascade.org/view.php?id=22809 + */ + struct TMP_IntCurvesFace_Intersector + { + BRepAdaptor_Surface _surf; + double _tol; + BRepIntCurveSurface_Inter _intcs; + vector _points; + BRepTopAdaptor_TopolTool _clsf; + + TMP_IntCurvesFace_Intersector(const TopoDS_Face& face, const double tol) + :_surf( face ), _tol( tol ), _clsf( new BRepAdaptor_HSurface(_surf) ) {} + Bnd_Box Bounding() const { Bnd_Box b; BRepBndLib::Add (_surf.Face(), b); return b; } + void Perform( const gp_Lin& line, const double w0, const double w1 ) + { + _points.clear(); + for ( _intcs.Init( _surf.Face(), line, _tol ); _intcs.More(); _intcs.Next() ) + if ( w0 <= _intcs.W() && _intcs.W() <= w1 ) + _points.push_back( _intcs.Point() ); + } + bool IsDone() const { return true; } + int NbPnt() const { return _points.size(); } + IntCurveSurface_TransitionOnCurve Transition( const int i ) const { return _points[ i-1 ].Transition(); } + double WParameter( const int i ) const { return _points[ i-1 ].W(); } + TopAbs_State ClassifyUVPoint(const gp_Pnt2d& p) { return _clsf.Classify( p, _tol ); } + }; +#define __IntCurvesFace_Intersector TMP_IntCurvesFace_Intersector +#else +#define __IntCurvesFace_Intersector IntCurvesFace_Intersector +#endif // -------------------------------------------------------------------------- /*! * \brief Intersector of TopoDS_Face with all GridLine's @@ -255,7 +302,7 @@ namespace TopoDS_Face _face; Grid* _grid; Bnd_Box _bndBox; - IntCurvesFace_Intersector* _surfaceInt; + __IntCurvesFace_Intersector* _surfaceInt; vector< std::pair< GridLine*, IntersectionPoint > > _intersections; FaceGridIntersector(): _grid(0), _surfaceInt(0) {} @@ -272,18 +319,18 @@ namespace GetCurveFaceIntersector(); return _bndBox; } - IntCurvesFace_Intersector* GetCurveFaceIntersector() + __IntCurvesFace_Intersector* GetCurveFaceIntersector() { if ( !_surfaceInt ) { - _surfaceInt = new IntCurvesFace_Intersector( _face, Precision::PConfusion() ); + _surfaceInt = new __IntCurvesFace_Intersector( _face, Precision::PConfusion() ); _bndBox = _surfaceInt->Bounding(); if ( _bndBox.IsVoid() ) BRepBndLib::Add (_face, _bndBox); } return _surfaceInt; } - bool IsThreadSafe() const; + bool IsThreadSafe(set< const Standard_Transient* >& noSafeTShapes) const; }; // -------------------------------------------------------------------------- /*! @@ -301,7 +348,7 @@ namespace gp_Cone _cone; gp_Sphere _sphere; gp_Torus _torus; - IntCurvesFace_Intersector* _surfaceInt; + __IntCurvesFace_Intersector* _surfaceInt; vector< IntersectionPoint > _intPoints; @@ -312,6 +359,7 @@ namespace void IntersectWithTorus (const GridLine& gridLine); void IntersectWithSurface (const GridLine& gridLine); + bool UVIsOnFace() const; void addIntPoint(const bool toClassify=true); bool isParamOnLineOK( const double linLength ) { @@ -879,12 +927,20 @@ namespace } //================================================================================ /* - * Store an intersection if it is In or ON the face + * Return true if (_u,_v) is on the face + */ + bool FaceLineIntersector::UVIsOnFace() const + { + TopAbs_State state = _surfaceInt->ClassifyUVPoint(gp_Pnt2d( _u,_v )); + return ( state == TopAbs_IN || state == TopAbs_ON ); + } + //================================================================================ + /* + * Store an intersection if it is IN or ON the face */ void FaceLineIntersector::addIntPoint(const bool toClassify) { - TopAbs_State state = toClassify ? _surfaceInt->ClassifyUVPoint(gp_Pnt2d( _u, _v )) : TopAbs_IN; - if ( state == TopAbs_IN || state == TopAbs_ON ) + if ( !toClassify || UVIsOnFace() ) { IntersectionPoint p; p._paramOnLine = _w; @@ -952,8 +1008,7 @@ namespace _w = linCone.ParamOnConic( i ); if ( !isParamOnLineOK( gridLine._length )) continue; ElSLib::Parameters(_cone, linCone.Point(i) ,_u,_v); - TopAbs_State state = _surfaceInt->ClassifyUVPoint(gp_Pnt2d( _u, _v )); - if ( state == TopAbs_IN || state == TopAbs_ON ) + if ( UVIsOnFace() ) { ElSLib::D1( _u, _v, _cone, P, du, dv ); norm = du ^ dv; @@ -1023,8 +1078,7 @@ namespace _w = linTorus.ParamOnLine( i ); if ( !isParamOnLineOK( gridLine._length )) continue; linTorus.ParamOnTorus( i, _u,_v ); - TopAbs_State state = _surfaceInt->ClassifyUVPoint(gp_Pnt2d( _u, _v )); - if ( state == TopAbs_IN || state == TopAbs_ON ) + if ( UVIsOnFace() ) { ElSLib::D1( _u, _v, _torus, P, du, dv ); norm = du ^ dv; @@ -1060,8 +1114,10 @@ namespace /* * check if its face can be safely intersected in a thread */ - bool FaceGridIntersector::IsThreadSafe() const + bool FaceGridIntersector::IsThreadSafe(set< const Standard_Transient* >& noSafeTShapes) const { + bool isSafe = true; + // check surface TopLoc_Location loc; Handle(Geom_Surface) surf = BRep_Tool::Surface( _face, loc ); @@ -1073,12 +1129,14 @@ namespace } if ( surf->IsKind( STANDARD_TYPE(Geom_BSplineSurface )) || surf->IsKind( STANDARD_TYPE(Geom_BezierSurface ))) - return false; + if ( !noSafeTShapes.insert((const Standard_Transient*) _face.TShape() ).second ) + isSafe = false; double f, l; TopExp_Explorer exp( _face, TopAbs_EDGE ); for ( ; exp.More(); exp.Next() ) { + bool edgeIsSafe = true; const TopoDS_Edge& e = TopoDS::Edge( exp.Current() ); // check 3d curve { @@ -1092,10 +1150,11 @@ namespace } if ( c->IsKind( STANDARD_TYPE(Geom_BSplineCurve )) || c->IsKind( STANDARD_TYPE(Geom_BezierCurve ))) - return false; + edgeIsSafe = false; } } // check 2d curve + if ( edgeIsSafe ) { Handle(Geom2d_Curve) c2 = BRep_Tool::CurveOnSurface( e, surf, loc, f, l); if ( !c2.IsNull() ) @@ -1107,11 +1166,13 @@ namespace } if ( c2->IsKind( STANDARD_TYPE(Geom2d_BSplineCurve )) || c2->IsKind( STANDARD_TYPE(Geom2d_BezierCurve ))) - return false; + edgeIsSafe = false; } } + if ( !edgeIsSafe && !noSafeTShapes.insert((const Standard_Transient*) e.TShape() ).second ) + isSafe = false; } - return true; + return isSafe; } //================================================================================ /*! @@ -1510,7 +1571,7 @@ namespace nbIntHex = 0; for ( size_t i = 0; i < intersectedHex.size(); ++i ) { - Hexahedron * hex = intersectedHex[ i ]; + Hexahedron * & hex = intersectedHex[ i ]; if ( hex ) { intHexInd[ nbIntHex++ ] = i; @@ -1538,6 +1599,14 @@ namespace --nbIntHex; } } + else if ( _nbCornerNodes > 3 && !hex ) + { + // all intersection of hex with geometry are at grid nodes + hex = new Hexahedron( *this ); + hex->init( i ); + intHexInd.push_back(0); + intHexInd[ nbIntHex++ ] = i; + } } // add elements resulted from hexadron intersection @@ -1545,7 +1614,7 @@ namespace intHexInd.resize( nbIntHex ); tbb::parallel_for ( tbb::blocked_range( 0, nbIntHex ), ParallelHexahedron( intersectedHex, intHexInd ), - tbb::simple_partitioner()); + tbb::simple_partitioner()); // ComputeElements() is called here for ( size_t i = 0; i < intHexInd.size(); ++i ) if ( Hexahedron * hex = intersectedHex[ intHexInd[ i ]] ) nbAdded += hex->addElements( helper ); @@ -1571,6 +1640,7 @@ namespace */ int Hexahedron::addElements(SMESH_MesherHelper& helper) { + int nbAdded = 0; // add elements resulted from hexahedron intersection //for ( size_t i = 0; i < _volumeDefs.size(); ++i ) { @@ -1596,9 +1666,10 @@ namespace break; } } + nbAdded += int ( _volumeDefs._nodes.size() > 0 ); } - return 1;//(int) _volumeDefs.size(); + return nbAdded; } //================================================================================ /*! @@ -1620,7 +1691,7 @@ namespace li.LineIndex10(), li.LineIndex01(), li.LineIndex11() }; - bool allLinksOut = true; + bool allLinksOut = true, hasLinks = false; for ( int iL = 0; iL < 4 && allLinksOut; ++iL ) // loop on 4 links parallel to iDir { const _Link& link = _hexLinks[ iL + 4*iDir ]; @@ -1640,10 +1711,13 @@ namespace firstIntPnt = link._intNodes[0]._intPoint; } - if ( firstIntPnt && firstIntPnt->_transition == Trans_IN ) - allLinksOut = false; + if ( firstIntPnt ) + { + hasLinks = true; + allLinksOut = ( firstIntPnt->_transition == Trans_OUT ); + } } - if ( allLinksOut ) + if ( hasLinks && allLinksOut ) return true; } return false; @@ -1847,6 +1921,9 @@ bool StdMeshers_Cartesian_3D::Compute(SMESH_Mesh & theMesh, // - skip a cell, if it is too small according to the size threshold // - add a hexahedron in the mesh, if all nodes are inside // - add a polyhedron in the mesh, if some nodes are inside and some outside + + _computeCanceled = false; + try { Grid grid; @@ -1884,9 +1961,15 @@ bool StdMeshers_Cartesian_3D::Compute(SMESH_Mesh & theMesh, if ( gridBox.IsOut( gp_Pnt( x0,y0,z0 )) || gridBox.IsOut( gp_Pnt( x1,y1,z1 ))) for ( size_t i = 0; i < facesItersectors.size(); ++i ) + { if ( !facesItersectors[i].IsInGrid( gridBox )) return error("The grid doesn't enclose the geometry"); +#ifdef ELLIPSOLID_WORKAROUND + delete facesItersectors[i]._surfaceInt, facesItersectors[i]._surfaceInt = 0; +#endif + } } + if ( _computeCanceled ) return false; #ifdef WITH_TBB { // copy partner faces and curves of not thread-safe types @@ -1894,8 +1977,7 @@ bool StdMeshers_Cartesian_3D::Compute(SMESH_Mesh & theMesh, BRepBuilderAPI_Copy copier; for ( size_t i = 0; i < facesItersectors.size(); ++i ) { - if ( !facesItersectors[i].IsThreadSafe() && - !tshapes.insert((const Standard_Transient*) facesItersectors[i]._face.TShape() ).second ) + if ( !facesItersectors[i].IsThreadSafe(tshapes) ) { copier.Perform( facesItersectors[i]._face ); facesItersectors[i]._face = TopoDS::Face( copier ); @@ -1922,9 +2004,13 @@ bool StdMeshers_Cartesian_3D::Compute(SMESH_Mesh & theMesh, helper.SetSubShape( solidExp.Current() ); helper.SetElementsOnShape( true ); + if ( _computeCanceled ) return false; + // create nodes on the geometry grid.ComputeNodes(helper); + if ( _computeCanceled ) return false; + // create volume elements Hexahedron hex( _hyp->GetSizeThreshold(), &grid ); int nbAdded = hex.MakeElements( helper );