# Extrusion
-import salome
+import salome, math
salome.salome_init()
-import GEOM
from salome.geom import geomBuilder
geompy = geomBuilder.New()
-import SMESH, SALOMEDS
+import SMESH
from salome.smesh import smeshBuilder
smesh = smeshBuilder.New()
-import SMESH_mechanic
+# create an empty mesh
+mesh = smesh.Mesh()
-#smesh = SMESH_mechanic.smesh
-mesh = SMESH_mechanic.mesh
+# add a node
+mesh.AddNode( 0.,0.,0. )
-# select the top face
-faces = geompy.SubShapeAllSorted(SMESH_mechanic.shape_mesh, geompy.ShapeType["FACE"])
-face = faces[7]
-geompy.addToStudyInFather(SMESH_mechanic.shape_mesh, face, "face circular top")
+# extrude a node into a line of 10 segments along the X axis
+ids = mesh.GetNodesId()
+stepVector = [1.,0.,0.]
+nbSteps = 10
+mesh.ExtrusionSweep( ids, stepVector, nbSteps, IsNodes=True )
-# create a vector for extrusion
-point = SMESH.PointStruct(0., 0., 5.)
-vector = SMESH.DirStruct(point)
+# create some groups
+lastNode = mesh.GetNodesId()[-1]
+lastNodeGroup = mesh.MakeGroupByIds( "node %s"% lastNode, SMESH.NODE, [lastNode])
+lineGroup = mesh.MakeGroupByIds( "line", SMESH.EDGE, mesh.GetElementsId() )
-# create a group to be extruded
-GroupTri = mesh.GroupOnGeom(face, "Group of faces (extrusion)", SMESH.FACE)
+# rotate the segments around the first node to get a mesh of a disk quarter
+axisZ = [0.,0.,0., 0.,0.,1.]
+groups = mesh.RotationSweepObject( lineGroup, axisZ, math.pi/2., 10, 1e-3, MakeGroups=True, TotalAngle=True )
-# perform extrusion of the group
-mesh.ExtrusionSweepObject(GroupTri, vector, 5)
+# extrude all faces into volumes
+obj = mesh
+stepVector = [0.,0.,-1.]
+nbSteps = 5
+groups = mesh.ExtrusionSweepObject2D( obj, stepVector, nbSteps, MakeGroups=True )
+
+# remove all segments created by the last command
+for g in groups:
+ if g.GetType() == SMESH.EDGE:
+ mesh.RemoveGroupWithContents( g )
+
+# extrude all segments into faces along Z
+obj = mesh
+stepVector = [0.,0.,1.]
+mesh.ExtrusionSweepObject1D( obj, stepVector, nbSteps )
+
+# extrude a group
+lineExtruded = None
+for g in mesh.GetGroups( SMESH.FACE ):
+ if g.GetName() == "line_extruded":
+ lineExtruded = g
+ break
+obj = lineExtruded
+stepVector = [0,-5.,0.]
+nbSteps = 1
+mesh.ExtrusionSweepObject( obj, stepVector, nbSteps )
+
+# extrude all nodes and triangle faces of the disk quarter, applying a scale factor
+diskGroup = None
+for g in mesh.GetGroups( SMESH.FACE ):
+ if g.GetName() == "line_rotated":
+ diskGroup = g
+ break
+crit = [ smesh.GetCriterion( SMESH.FACE, SMESH.FT_ElemGeomType,'=',SMESH.Geom_TRIANGLE ),
+ smesh.GetCriterion( SMESH.FACE, SMESH.FT_BelongToMeshGroup,'=', diskGroup )]
+trianglesFilter = smesh.GetFilterFromCriteria( crit )
+
+nodes = [ diskGroup ]
+edges = []
+faces = [ trianglesFilter ]
+stepVector = [0,0,1]
+nbSteps = 10
+mesh.ExtrusionSweepObjects( nodes, edges, faces, stepVector, nbSteps, scaleFactors=[0.5], linearVariation=True )
+
+# extrude a cylindrical group of faces by normal
+cylGroup = None
+for g in mesh.GetGroups( SMESH.FACE ):
+ if g.GetName().startswith("node "):
+ cylGroup = g
+ break
+
+elements = cylGroup
+stepSize = 5.
+nbSteps = 2
+mesh.ExtrusionByNormal( elements, stepSize, nbSteps )
salome.sg.updateObjBrowser()
tmp2/smesh_algorithm.py \
tmp2/StdMeshersBuilder.py \
tmp2/smeshstudytools.py \
- tmp1/smeshBuilder.py
-FILE_PATTERNS =
+ tmp1/smeshBuilder.py \
+ @CMAKE_CURRENT_SOURCE_DIR@/input
+FILE_PATTERNS = tui_*.doc
IMAGE_PATH = @CMAKE_CURRENT_SOURCE_DIR@/images
RECURSIVE = NO
-EXAMPLE_PATH = @CMAKE_SOURCE_DIR@/src/SMESH_SWIG
+EXAMPLE_PATH = @CMAKE_SOURCE_DIR@/src/SMESH_SWIG @CMAKE_SOURCE_DIR@/doc/salome/examples
#---------------------------------------------------------------------------
#HTML related options
#---------------------------------------------------------------------------
GENERATE_TAGFILE = smeshpy_doc.tag
SEARCHENGINE = YES
+
+#---------------------------------------------------------------------------
+#Custom commands
+#---------------------------------------------------------------------------
+ALIASES += tui_script{1}="\include \1 <a href=\"../../examples/SMESH/\1\">Download this script</a>"
if ( myProjFace.IsDone() && myProjFace.LowerDistance() <= myTol )
{
// check relatively to the face
- Quantity_Parameter u, v;
+ Standard_Real u, v;
myProjFace.LowerDistanceParameters(u, v);
gp_Pnt2d aProjPnt (u, v);
BRepClass_FaceClassifier aClsf ( TopoDS::Face( myShape ), aProjPnt, myTol );
#define _OBJECTPOOL_HXX_
#include <vector>
-//#include <stack>
#include <iostream>
+#include "SMDS_Iterator.hxx"
+
namespace
{
// assure deallocation of memory of a vector
}
}
+template<class X> class ObjectPoolIterator;
+
template<class X> class ObjectPool
{
private:
- std::vector<X*> _chunkList;
+ std::vector<X*> _chunkList;
std::vector<bool> _freeList;
- int _nextFree;
- int _maxAvail;
- int _chunkSize;
- int _maxOccupied;
- int _nbHoles;
- int _lastDelChunk;
+ int _nextFree; // either the 1st hole or last added
+ int _maxAvail; // nb allocated elements
+ int _chunkSize;
+ int _maxOccupied; // max used ID
+ int _nbHoles;
+ int _lastDelChunk;
+
+ friend class ObjectPoolIterator<X>;
int getNextFree()
{
}
public:
- ObjectPool(int nblk)
+ ObjectPool(int nblk = 1024)
{
- _chunkSize = nblk;
- _nextFree = 0;
- _maxAvail = 0;
- _maxOccupied = 0;
- _nbHoles = 0;
+ _chunkSize = nblk;
+ _nextFree = 0;
+ _maxAvail = 0;
+ _maxOccupied = -1;
+ _nbHoles = 0;
+ _lastDelChunk = 0;
_chunkList.clear();
_freeList.clear();
- _lastDelChunk = 0;
}
virtual ~ObjectPool()
_freeList.insert(_freeList.end(), _chunkSize, true);
_maxAvail += _chunkSize;
_freeList[_nextFree] = false;
- obj = newChunk; // &newChunk[0];
+ obj = newChunk;
}
else
{
int chunkId = _nextFree / _chunkSize;
int rank = _nextFree - chunkId * _chunkSize;
_freeList[_nextFree] = false;
- obj = _chunkList[chunkId] + rank; // &_chunkList[chunkId][rank];
+ obj = _chunkList[chunkId] + rank;
}
- if (_nextFree < _maxOccupied)
+ if (_nextFree <= _maxOccupied)
{
_nbHoles-=1;
}
{
_maxOccupied = _nextFree;
}
- //obj->init();
return obj;
}
if (toFree < _nextFree)
_nextFree = toFree;
if (toFree < _maxOccupied)
- _nbHoles += 1;
+ ++_nbHoles;
+ else
+ --_maxOccupied;
_lastDelChunk = i;
- //obj->clean();
- //checkDelete(i); compactage non fait
}
void clear()
clearVector( _freeList );
}
+ // nb allocated elements
+ size_t size() const
+ {
+ return _freeList.size();
+ }
+
+ // nb used elements
+ size_t nbElements() const
+ {
+ return _maxOccupied + 1 - _nbHoles;
+ }
+
+ // return an element w/o any check
+ const X* operator[]( size_t i ) const // i < size()
+ {
+ int chunkId = i / _chunkSize;
+ int rank = i - chunkId * _chunkSize;
+ return _chunkList[ chunkId ] + rank;
+ }
+
+ // return only being used element
+ const X* at( size_t i ) const // i < size()
+ {
+ if ( i >= size() || _freeList[ i ] )
+ return 0;
+
+ int chunkId = i / _chunkSize;
+ int rank = i - chunkId * _chunkSize;
+ return _chunkList[ chunkId ] + rank;
+ }
+
// void destroy(int toFree)
// {
// // no control 0<= toFree < _freeList.size()
};
+template<class X> class ObjectPoolIterator : public SMDS_Iterator<const X*>
+{
+ const ObjectPool<X>& _pool;
+ int _i, _nbFound;
+public:
+
+ ObjectPoolIterator( const ObjectPool<X>& pool ) : _pool( pool ), _i( 0 ), _nbFound( 0 )
+ {
+ if ( more() && _pool._freeList[ _i ] == true )
+ {
+ next();
+ --_nbFound;
+ }
+ }
+
+ virtual bool more()
+ {
+ return ( _i <= _pool._maxOccupied && _nbFound < (int)_pool.nbElements() );
+ }
+
+ virtual const X* next()
+ {
+ const X* x = 0;
+ if ( more() )
+ {
+ x = _pool[ _i ];
+
+ ++_nbFound;
+
+ for ( ++_i; _i <= _pool._maxOccupied; ++_i )
+ if ( _pool._freeList[ _i ] == false )
+ break;
+ }
+ return x;
+ }
+};
+
#endif
bool SMDS_MeshGroup::Contains(const SMDS_MeshElement * theElem) const
{
- return myElements.find(theElem)!=myElements.end();
+ return myElements.find(theElem) != myElements.end();
}
//=======================================================================
MESSAGE( "SMESH_MesherHelper::CheckNodeUV() failed to project" );
return false;
}
- Quantity_Parameter U,V;
+ Standard_Real U,V;
projector.LowerDistanceParameters(U,V);
uv.SetCoord( U,V );
surfPnt = surface->Value( U, V );
MESSAGE( "SMESH_MesherHelper::CheckNodeU() failed to project" );
return false;
}
- Quantity_Parameter U = projector->LowerDistanceParameter();
+ Standard_Real U = projector->LowerDistanceParameter();
u = double( U );
curvPnt = curve->Value( u );
dist = nodePnt.Distance( curvPnt );
//=============================================================================
/*!
- *
+ * Don't use it!
*/
//=============================================================================
virtual SMDS_ElemIteratorPtr GetElements() const = 0;
virtual int GetID (const int theIndex);
- // use it for iterations 1..Extent()
+ // DON'T use it for iterations 1..Extent()
virtual int GetTic() const = 0;
// Elem geom
- QGroupBox* elemsGrp = new QGroupBox( tr( "SMESH_ELEMENTS" ), mainFrame() );
+ QGroupBox* elemsGrp = new QGroupBox( tr( "ELEMENTS" ), mainFrame() );
+ elemsGrp->setToolTip( tr("ELEMENTS_TOOLTIP") );
QLabel* label = new QLabel( tr( "SMESH_GEOM" ), elemsGrp );
myElemGeomBtn = new QPushButton( elemsGrp );
myElemGeomBtn->setCheckable(true);
}
if (entityType()) {
- if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
- aViewWindow->SetSelectionMode(VolumeSelection);
SMESH::SetFilter(new SMESHGUI_VolumesFilter());
- } else {
if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
- aViewWindow->SetSelectionMode(FaceSelection);
+ aViewWindow->SetSelectionMode(VolumeSelection); // here myActor set to a filter
+ } else {
if (myFilterType == SMESH::TriaFilter)
SMESH::SetFilter(new SMESHGUI_TriangleFilter());
else if (myFilterType == SMESH::QuadFilter)
SMESH::SetFilter(new SMESHGUI_QuadrangleFilter());
else
SMESH::SetFilter(new SMESHGUI_FacesFilter());
+ if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+ aViewWindow->SetSelectionMode(FaceSelection); // here myActor set to a filter
}
}
<source>SMESH_CREATE_GROUP_FROM_GEOM</source>
<translation>Create Groups from Geometry</translation>
</message>
+ <message>
+ <source>ELEMENTS</source>
+ <translation>Elements</translation>
+ </message>
+ <message>
+ <source>ELEMENTS_TOOLTIP</source>
+ <translation>No 0D elements</translation>
+ </message>
</context>
<context>
<name>SMESHGUI_MeshOrderDlg</name>
SMDSAbs_ElementType elemType,
SMDS_ElemIteratorPtr theElemIt = SMDS_ElemIteratorPtr(),
double tolerance = NodeRadius );
- void getElementsNearPoint( const gp_Pnt& point, TIDSortedElemSet& foundElems );
- void getElementsNearLine ( const gp_Ax1& line, TIDSortedElemSet& foundElems);
- void getElementsInSphere ( const gp_XYZ& center,
- const double radius, TIDSortedElemSet& foundElems);
- size_t getSize() { return std::max( _size, _elements.size() ); }
- virtual ~ElementBndBoxTree();
+ void prepare(); // !!!call it before calling the following methods!!!
+ void getElementsNearPoint( const gp_Pnt& point, vector<const SMDS_MeshElement*>& foundElems );
+ void getElementsNearLine ( const gp_Ax1& line, vector<const SMDS_MeshElement*>& foundElems);
+ void getElementsInSphere ( const gp_XYZ& center,
+ const double radius,
+ vector<const SMDS_MeshElement*>& foundElems);
protected:
- ElementBndBoxTree():_size(0) {}
+ ElementBndBoxTree() {}
SMESH_Octree* newChild() const { return new ElementBndBoxTree; }
void buildChildrenData();
Bnd_B3d* buildRootBox();
struct ElementBox : public Bnd_B3d
{
const SMDS_MeshElement* _element;
- int _refCount; // an ElementBox can be included in several tree branches
- ElementBox(const SMDS_MeshElement* elem, double tolerance);
+ bool _isMarked;
+ void init(const SMDS_MeshElement* elem, double tolerance);
};
vector< ElementBox* > _elements;
- size_t _size;
+
+ typedef ObjectPool< ElementBox > TElementBoxPool;
+
+ //!< allocator of ElementBox's and SMESH_TreeLimit
+ struct LimitAndPool : public SMESH_TreeLimit
+ {
+ TElementBoxPool _elBoPool;
+ std::vector< ElementBox* > _markedElems;
+ LimitAndPool():SMESH_TreeLimit( MaxLevel, /*minSize=*/0. ) {}
+ };
+ LimitAndPool* getLimitAndPool() const
+ {
+ SMESH_TreeLimit* limitAndPool = const_cast< SMESH_TreeLimit* >( myLimit );
+ return static_cast< LimitAndPool* >( limitAndPool );
+ }
};
//================================================================================
*/
//================================================================================
- ElementBndBoxTree::ElementBndBoxTree(const SMDS_Mesh& mesh, SMDSAbs_ElementType elemType, SMDS_ElemIteratorPtr theElemIt, double tolerance)
- :SMESH_Octree( new SMESH_TreeLimit( MaxLevel, /*minSize=*/0. ))
+ ElementBndBoxTree::ElementBndBoxTree(const SMDS_Mesh& mesh,
+ SMDSAbs_ElementType elemType,
+ SMDS_ElemIteratorPtr theElemIt,
+ double tolerance)
+ :SMESH_Octree( new LimitAndPool() )
{
int nbElems = mesh.GetMeshInfo().NbElements( elemType );
_elements.reserve( nbElems );
+ TElementBoxPool& elBoPool = getLimitAndPool()->_elBoPool;
+
SMDS_ElemIteratorPtr elemIt = theElemIt ? theElemIt : mesh.elementsIterator( elemType );
while ( elemIt->more() )
- _elements.push_back( new ElementBox( elemIt->next(),tolerance ));
-
+ {
+ ElementBox* eb = elBoPool.getNew();
+ eb->init( elemIt->next(), tolerance );
+ _elements.push_back( eb );
+ }
compute();
}
- //================================================================================
- /*!
- * \brief Destructor
- */
- //================================================================================
-
- ElementBndBoxTree::~ElementBndBoxTree()
- {
- for ( size_t i = 0; i < _elements.size(); ++i )
- if ( --_elements[i]->_refCount <= 0 )
- delete _elements[i];
- }
-
//================================================================================
/*!
* \brief Return the maximal box
for (int j = 0; j < 8; j++)
{
if ( !_elements[i]->IsOut( *myChildren[j]->getBox() ))
- {
- _elements[i]->_refCount++;
((ElementBndBoxTree*)myChildren[j])->_elements.push_back( _elements[i]);
- }
}
- _elements[i]->_refCount--;
}
- _size = _elements.size();
+ //_size = _elements.size();
SMESHUtils::FreeVector( _elements ); // = _elements.clear() + free memory
for (int j = 0; j < 8; j++)
if ((int) child->_elements.size() <= MaxNbElemsInLeaf )
child->myIsLeaf = true;
- if ( child->_elements.capacity() - child->_elements.size() > 1000 )
+ if ( child->isLeaf() && child->_elements.capacity() > child->_elements.size() )
SMESHUtils::CompactVector( child->_elements );
}
}
+ //================================================================================
+ /*!
+ * \brief Un-mark all elements
+ */
+ //================================================================================
+
+ void ElementBndBoxTree::prepare()
+ {
+ // TElementBoxPool& elBoPool = getElementBoxPool();
+ // for ( size_t i = 0; i < elBoPool.nbElements(); ++i )
+ // const_cast< ElementBox* >( elBoPool[ i ])->_isMarked = false;
+ }
+
//================================================================================
/*!
* \brief Return elements which can include the point
*/
//================================================================================
- void ElementBndBoxTree::getElementsNearPoint( const gp_Pnt& point,
- TIDSortedElemSet& foundElems)
+ void ElementBndBoxTree::getElementsNearPoint( const gp_Pnt& point,
+ vector<const SMDS_MeshElement*>& foundElems)
{
if ( getBox()->IsOut( point.XYZ() ))
return;
if ( isLeaf() )
{
+ LimitAndPool* pool = getLimitAndPool();
+
for ( size_t i = 0; i < _elements.size(); ++i )
- if ( !_elements[i]->IsOut( point.XYZ() ))
- foundElems.insert( _elements[i]->_element );
+ if ( !_elements[i]->IsOut( point.XYZ() ) &&
+ !_elements[i]->_isMarked )
+ {
+ foundElems.push_back( _elements[i]->_element );
+ _elements[i]->_isMarked = true;
+ pool->_markedElems.push_back( _elements[i] );
+ }
}
else
{
for (int i = 0; i < 8; i++)
((ElementBndBoxTree*) myChildren[i])->getElementsNearPoint( point, foundElems );
+
+ if ( level() == 0 )
+ {
+ LimitAndPool* pool = getLimitAndPool();
+ for ( size_t i = 0; i < pool->_markedElems.size(); ++i )
+ pool->_markedElems[i]->_isMarked = false;
+ pool->_markedElems.clear();
+ }
}
}
*/
//================================================================================
- void ElementBndBoxTree::getElementsNearLine( const gp_Ax1& line,
- TIDSortedElemSet& foundElems)
+ void ElementBndBoxTree::getElementsNearLine( const gp_Ax1& line,
+ vector<const SMDS_MeshElement*>& foundElems)
{
if ( getBox()->IsOut( line ))
return;
if ( isLeaf() )
{
+ LimitAndPool* pool = getLimitAndPool();
+
for ( size_t i = 0; i < _elements.size(); ++i )
- if ( !_elements[i]->IsOut( line ))
- foundElems.insert( _elements[i]->_element );
+ if ( !_elements[i]->IsOut( line ) &&
+ !_elements[i]->_isMarked )
+ {
+ foundElems.push_back( _elements[i]->_element );
+ _elements[i]->_isMarked = true;
+ pool->_markedElems.push_back( _elements[i] );
+ }
}
else
{
for (int i = 0; i < 8; i++)
((ElementBndBoxTree*) myChildren[i])->getElementsNearLine( line, foundElems );
+
+ if ( level() == 0 )
+ {
+ LimitAndPool* pool = getLimitAndPool();
+ for ( size_t i = 0; i < pool->_markedElems.size(); ++i )
+ pool->_markedElems[i]->_isMarked = false;
+ pool->_markedElems.clear();
+ }
}
}
*/
//================================================================================
- void ElementBndBoxTree::getElementsInSphere ( const gp_XYZ& center,
- const double radius,
- TIDSortedElemSet& foundElems)
+ void ElementBndBoxTree::getElementsInSphere ( const gp_XYZ& center,
+ const double radius,
+ vector<const SMDS_MeshElement*>& foundElems)
{
if ( getBox()->IsOut( center, radius ))
return;
if ( isLeaf() )
{
+ LimitAndPool* pool = getLimitAndPool();
+
for ( size_t i = 0; i < _elements.size(); ++i )
- if ( !_elements[i]->IsOut( center, radius ))
- foundElems.insert( _elements[i]->_element );
+ if ( !_elements[i]->IsOut( center, radius ) &&
+ !_elements[i]->_isMarked )
+ {
+ foundElems.push_back( _elements[i]->_element );
+ _elements[i]->_isMarked = true;
+ pool->_markedElems.push_back( _elements[i] );
+ }
}
else
{
for (int i = 0; i < 8; i++)
((ElementBndBoxTree*) myChildren[i])->getElementsInSphere( center, radius, foundElems );
+
+ if ( level() == 0 )
+ {
+ LimitAndPool* pool = getLimitAndPool();
+ for ( size_t i = 0; i < pool->_markedElems.size(); ++i )
+ pool->_markedElems[i]->_isMarked = false;
+ pool->_markedElems.clear();
+ }
}
}
*/
//================================================================================
- ElementBndBoxTree::ElementBox::ElementBox(const SMDS_MeshElement* elem, double tolerance)
+ void ElementBndBoxTree::ElementBox::init(const SMDS_MeshElement* elem, double tolerance)
{
_element = elem;
- _refCount = 1;
+ _isMarked = false;
SMDS_ElemIteratorPtr nIt = elem->nodesIterator();
while ( nIt->more() )
- Add( SMESH_TNodeXYZ( nIt->next() ));
+ Add( SMESH_NodeXYZ( nIt->next() ));
Enlarge( tolerance );
}
anExtCC.Init( lineCurve, edge.Value() );
if ( anExtCC.NbExtrema() > 0 && anExtCC.LowerDistance() <= tol)
{
- Quantity_Parameter pl, pe;
+ Standard_Real pl, pe;
anExtCC.LowerDistanceParameters( pl, pe );
param += pl;
if ( ++nbInts == 2 )
{
_ebbTree[_elementType] = new ElementBndBoxTree( *_mesh, type, _meshPartIt, tolerance );
}
- TIDSortedElemSet suspectElems;
+ else
+ {
+ _ebbTree[ type ]->prepare();
+ }
+ vector< const SMDS_MeshElement* > suspectElems;
_ebbTree[ type ]->getElementsNearPoint( point, suspectElems );
- TIDSortedElemSet::iterator elem = suspectElems.begin();
+ vector< const SMDS_MeshElement* >::iterator elem = suspectElems.begin();
for ( ; elem != suspectElems.end(); ++elem )
if ( !SMESH_MeshAlgos::IsOut( *elem, point, tolerance ))
foundElements.push_back( *elem );
ElementBndBoxTree*& ebbTree = _ebbTree[ type ];
if ( !ebbTree )
ebbTree = new ElementBndBoxTree( *_mesh, type, _meshPartIt );
+ else
+ ebbTree->prepare();
- TIDSortedElemSet suspectElems;
+ vector<const SMDS_MeshElement*> suspectElems;
ebbTree->getElementsNearPoint( point, suspectElems );
if ( suspectElems.empty() && ebbTree->maxSize() > 0 )
radius = ebbTree->maxSize() / pow( 2., getTreeHeight()) / 2;
while ( suspectElems.empty() )
{
+ ebbTree->prepare();
ebbTree->getElementsInSphere( point.XYZ(), radius, suspectElems );
radius *= 1.1;
}
}
double minDist = std::numeric_limits<double>::max();
multimap< double, const SMDS_MeshElement* > dist2face;
- TIDSortedElemSet::iterator elem = suspectElems.begin();
+ vector<const SMDS_MeshElement*>::iterator elem = suspectElems.begin();
for ( ; elem != suspectElems.end(); ++elem )
{
double dist = SMESH_MeshAlgos::GetDistance( *elem, point );
ElementBndBoxTree*& ebbTree = _ebbTree[ SMDSAbs_Face ];
if ( !ebbTree )
ebbTree = new ElementBndBoxTree( *_mesh, _elementType, _meshPartIt );
+ else
+ ebbTree->prepare();
// Algo: analyse transition of a line starting at the point through mesh boundary;
// try three lines parallel to axis of the coordinate system and perform rough
gp_Ax1 lineAxis( point, axisDir[axis]);
gp_Lin line ( lineAxis );
- TIDSortedElemSet suspectFaces; // faces possibly intersecting the line
+ vector<const SMDS_MeshElement*> suspectFaces; // faces possibly intersecting the line
+ if ( axis > 0 ) ebbTree->prepare();
ebbTree->getElementsNearLine( lineAxis, suspectFaces );
// Intersect faces with the line
map< double, TInters > & u2inters = paramOnLine2TInters[ axis ];
- TIDSortedElemSet::iterator face = suspectFaces.begin();
+ vector<const SMDS_MeshElement*>::iterator face = suspectFaces.begin();
for ( ; face != suspectFaces.end(); ++face )
{
// get face plane
ElementBndBoxTree*& ebbTree = _ebbTree[ type ];
if ( !ebbTree )
ebbTree = new ElementBndBoxTree( *_mesh, _elementType, _meshPartIt );
+ else
+ ebbTree->prepare();
- TIDSortedElemSet suspectFaces; // elements possibly intersecting the line
- ebbTree->getElementsNearLine( line, suspectFaces );
- foundElems.assign( suspectFaces.begin(), suspectFaces.end());
+ ebbTree->getElementsNearLine( line, foundElems );
}
//=======================================================================
ElementBndBoxTree*& ebbTree = _ebbTree[ type ];
if ( !ebbTree )
ebbTree = new ElementBndBoxTree( *_mesh, _elementType, _meshPartIt );
+ else
+ ebbTree->prepare();
- TIDSortedElemSet suspectFaces; // elements possibly intersecting the line
- ebbTree->getElementsInSphere( center, radius, suspectFaces );
- foundElems.assign( suspectFaces.begin(), suspectFaces.end() );
+ ebbTree->getElementsInSphere( center, radius, foundElems );
}
//=======================================================================
{
int aSize = aGroupDS->Extent();
aRes->length(aSize);
- for (int i = 0; i < aSize; i++)
- aRes[i] = aGroupDS->GetID(i+1);
+ SMDS_ElemIteratorPtr it = aGroupDS->GetElements();
+ for (int i = 0; it->more(); i++)
+ aRes[i] = it->next()->GetID();
if ( 0 < aSize && aSize < 100 ) // for comfortable testing ;)
std::sort( &aRes[0], &aRes[0]+aSize );
# - a GEOM point
# @return the list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
# @ingroup l2_modif_extrurev
+ # @ref tui_extrusion example
def ExtrusionSweepObjects(self, nodes, edges, faces, StepVector, NbOfSteps, MakeGroups=False,
scaleFactors=[], linearVariation=False, basePoint=[] ):
unRegister = genObjUnRegister()
# @param IsNodes is True if elements with given ids are nodes
# @return the list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
# @ingroup l2_modif_extrurev
+ # @ref tui_extrusion example
def ExtrusionSweep(self, IDsOfElements, StepVector, NbOfSteps, MakeGroups=False, IsNodes = False):
n,e,f = [],[],[]
if IsNodes: n = IDsOfElements
# @return the list of created groups (SMESH_GroupBase) if \a MakeGroups=True,
# empty list otherwise.
# @ingroup l2_modif_extrurev
+ # @ref tui_extrusion example
def ExtrusionByNormal(self, Elements, StepSize, NbOfSteps,
ByAverageNormal=False, UseInputElemsOnly=True, MakeGroups=False, Dim = 2):
unRegister = genObjUnRegister()
# @param IsNodes is True if elements to extrude are nodes
# @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
# @ingroup l2_modif_extrurev
+ # @ref tui_extrusion example
def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
n,e,f = [],[],[]
if IsNodes: n = theObject
# @param MakeGroups to generate new groups from existing ones
# @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
# @ingroup l2_modif_extrurev
+ # @ref tui_extrusion example
def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
# @param MakeGroups forces the generation of new groups from existing ones
# @return list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
# @ingroup l2_modif_extrurev
+ # @ref tui_extrusion example
def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups)
# @param MakeGroups forces the generation of new groups from existing ones
# @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error
# @ingroup l2_modif_extrurev
+ # @ref tui_extrusion_along_path example
def ExtrusionAlongPathObjects(self, Nodes, Edges, Faces, PathMesh, PathShape=None,
NodeStart=1, HasAngles=False, Angles=[], LinearVariation=False,
HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False):
# @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error if MakeGroups=True,
# only SMESH::Extrusion_Error otherwise
# @ingroup l2_modif_extrurev
+ # @ref tui_extrusion_along_path example
def ExtrusionAlongPathX(self, Base, Path, NodeStart,
HasAngles=False, Angles=[], LinearVariation=False,
HasRefPoint=False, RefPoint=[0,0,0], MakeGroups=False,
# @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error if MakeGroups=True,
# only SMESH::Extrusion_Error otherwise
# @ingroup l2_modif_extrurev
+ # @ref tui_extrusion_along_path example
def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
MakeGroups=False, LinearVariation=False):
# @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error if MakeGroups=True,
# only SMESH::Extrusion_Error otherwise
# @ingroup l2_modif_extrurev
+ # @ref tui_extrusion_along_path example
def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
MakeGroups=False, LinearVariation=False):
# @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error if MakeGroups=True,
# only SMESH::Extrusion_Error otherwise
# @ingroup l2_modif_extrurev
+ # @ref tui_extrusion_along_path example
def ExtrusionAlongPathObject1D(self, theObject, PathMesh, PathShape, NodeStart,
HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
MakeGroups=False, LinearVariation=False):
# @return list of created groups (SMESH_GroupBase) and SMESH::Extrusion_Error if MakeGroups=True,
# only SMESH::Extrusion_Error otherwise
# @ingroup l2_modif_extrurev
+ # @ref tui_extrusion_along_path example
def ExtrusionAlongPathObject2D(self, theObject, PathMesh, PathShape, NodeStart,
HasAngles=False, Angles=[], HasRefPoint=False, RefPoint=[],
MakeGroups=False, LinearVariation=False):
proj.Perform( testPnt );
if ( proj.IsDone() && proj.NbPoints() > 0 )
{
- Quantity_Parameter u,v;
+ Standard_Real u,v;
proj.LowerDistanceParameters( u,v );
if ( proj.LowerDistance() <= 0.1 * _grid->_tol )
proj.Perform( gc );
if ( !proj.IsDone() || proj.NbPoints() < 1 )
continue;
- Quantity_Parameter U,V;
+ Standard_Real U,V;
proj.LowerDistanceParameters(U,V);
gp_XY uv( U,V );
classifier.Perform( geomFace, uv, clsfTol );
#include <Geom_Surface.hxx>
#include <NCollection_DefineArray2.hxx>
#include <Precision.hxx>
-#include <Quantity_Parameter.hxx>
#include <TColStd_SequenceOfInteger.hxx>
#include <TColStd_SequenceOfReal.hxx>
#include <TColgp_SequenceOfXY.hxx>
gp_Ax1 LastSegment(double& segLen, _EdgesOnShape& eos) const;
gp_XY LastUV( const TopoDS_Face& F, _EdgesOnShape& eos, int which=-1 ) const;
bool IsOnEdge() const { return _2neibors; }
+ bool IsOnFace() const { return ( _nodes[0]->GetPosition()->GetDim() == 2 ); }
gp_XYZ Copy( _LayerEdge& other, _EdgesOnShape& eos, SMESH_MesherHelper& helper );
void SetCosin( double cosin );
void SetNormal( const gp_XYZ& n ) { _normal = n; }
// define allowed thickness
computeGeomSize( data ); // compute data._geomSize and _LayerEdge::_maxLen
- data._maxThickness = 0;
- data._minThickness = 1e100;
- list< const StdMeshers_ViscousLayers* >::iterator hyp = data._hyps.begin();
- for ( ; hyp != data._hyps.end(); ++hyp )
- {
- data._maxThickness = Max( data._maxThickness, (*hyp)->GetTotalThickness() );
- data._minThickness = Min( data._minThickness, (*hyp)->GetTotalThickness() );
- }
- //const double tgtThick = /*Min( 0.5 * data._geomSize, */data._maxThickness;
// Find shapes needing smoothing; such a shape has _LayerEdge._normal on it's
// boundary inclined to the shape at a sharp angle
isOK = false;
return p.XYZ();
}
- Quantity_Parameter U,V;
+ Standard_Real U,V;
projector.LowerDistanceParameters(U,V);
uv.SetCoord( U,V );
}
_EdgesOnShape& eos = data._edgesOnShape[ iS ];
if ( eos._edges.empty() )
continue;
- // get neighbor faces intersection with which should not be considered since
+ // get neighbor faces, intersection with which should not be considered since
// collisions are avoided by means of smoothing
set< TGeomID > neighborFaces;
if ( eos._hyp.ToSmooth() )
}
}
}
+
+ data._maxThickness = 0;
+ data._minThickness = 1e100;
+ list< const StdMeshers_ViscousLayers* >::iterator hyp = data._hyps.begin();
+ for ( ; hyp != data._hyps.end(); ++hyp )
+ {
+ data._maxThickness = Max( data._maxThickness, (*hyp)->GetTotalThickness() );
+ data._minThickness = Min( data._minThickness, (*hyp)->GetTotalThickness() );
+ }
+
+ // Limit inflation step size by geometry size found by intersecting
+ // normals of _LayerEdge's with mesh faces
+ if ( data._stepSize > 0.3 * data._geomSize )
+ limitStepSize( data, 0.3 * data._geomSize );
+
+ if ( data._stepSize > data._minThickness )
+ limitStepSize( data, data._minThickness );
+
+
+ // -------------------------------------------------------------------------
+ // Detect _LayerEdge which can't intersect with opposite or neighbor layer,
+ // so no need in detecting intersection at each inflation step
+ // -------------------------------------------------------------------------
+
+ int nbSteps = data._maxThickness / data._stepSize;
+ if ( nbSteps < 3 || nbSteps * data._n2eMap.size() < 100000 )
+ return;
+
+ vector< const SMDS_MeshElement* > closeFaces;
+ int nbDetected = 0;
+
+ for ( size_t iS = 0; iS < data._edgesOnShape.size(); ++iS )
+ {
+ _EdgesOnShape& eos = data._edgesOnShape[ iS ];
+ if ( eos._edges.empty() || eos.ShapeType() != TopAbs_FACE )
+ continue;
+
+ for ( size_t i = 0; i < eos.size(); ++i )
+ {
+ SMESH_NodeXYZ p( eos[i]->_nodes[0] );
+ double radius = data._maxThickness + 2 * eos[i]->_maxLen;
+ closeFaces.clear();
+ searcher->GetElementsInSphere( p, radius, SMDSAbs_Face, closeFaces );
+
+ bool toIgnore = true;
+ for ( size_t iF = 0; iF < closeFaces.size() && toIgnore; ++iF )
+ if ( !( toIgnore = ( closeFaces[ iF ]->getshapeId() == eos._shapeID ||
+ data._ignoreFaceIds.count( closeFaces[ iF ]->getshapeId() ))))
+ {
+ // check if a _LayerEdge will inflate in a direction opposite to a direction
+ // toward a close face
+ bool allBehind = true;
+ for ( int iN = 0; iN < closeFaces[ iF ]->NbCornerNodes() && allBehind; ++iN )
+ {
+ SMESH_NodeXYZ pi( closeFaces[ iF ]->GetNode( iN ));
+ allBehind = (( pi - p ) * eos[i]->_normal < 0.1 * data._stepSize );
+ }
+ toIgnore = allBehind;
+ }
+
+
+ if ( toIgnore ) // no need to detect intersection
+ {
+ eos[i]->Set( _LayerEdge::INTERSECTED );
+ ++nbDetected;
+ }
+ }
+ }
+
+ debugMsg( "Nb LE to intersect " << data._n2eMap.size()-nbDetected << ", ignore " << nbDetected );
+
+ return;
}
//================================================================================
{
SMESH_MesherHelper helper( *_mesh );
- // Limit inflation step size by geometry size found by itersecting
- // normals of _LayerEdge's with mesh faces
- if ( data._stepSize > 0.3 * data._geomSize )
- limitStepSize( data, 0.3 * data._geomSize );
-
const double tgtThick = data._maxThickness;
- if ( data._stepSize > data._minThickness )
- limitStepSize( data, data._minThickness );
if ( data._stepSize < 1. )
data._epsilon = data._stepSize * 1e-7;
break;
}
#endif
+
// new step size
limitStepSize( data, 0.25 * distToIntersection );
if ( data._stepSizeNodes[0] )
_LayerEdge* edge = eos._edges[i];
if ( edge->_nodes.size() < 2 ) continue;
SMESH_TNodeXYZ tgtXYZ = edge->_nodes.back();
+ //SMESH_TNodeXYZ prevXYZ = edge->_nodes[0];
gp_XYZ prevXYZ = edge->PrevCheckPos( &eos );
//const gp_XYZ& prevXYZ = edge->PrevPos();
for ( size_t j = 0; j < edge->_simplices.size(); ++j )
if ( iFrom >= iTo ) continue;
_LayerEdge* e0 = _eos[iFrom]->_2neibors->_edges[0];
_LayerEdge* e1 = _eos[iTo-1]->_2neibors->_edges[1];
- gp_XY uv0 = ( e0 == eV0 ) ? uvV0 : e0->LastUV( F, _eos );
- gp_XY uv1 = ( e1 == eV1 ) ? uvV1 : e1->LastUV( F, _eos );
- double param0 = ( iFrom == 0 ) ? 0. : _leParams[ iFrom-1 ];
- double param1 = _leParams[ iTo ];
- const gp_XY rangeUV = uv1 - uv0;
+ gp_XY uv0 = ( e0 == eV0 ) ? uvV0 : e0->LastUV( F, _eos );
+ gp_XY uv1 = ( e1 == eV1 ) ? uvV1 : e1->LastUV( F, _eos );
+ double param0 = ( iFrom == 0 ) ? 0. : _leParams[ iFrom-1 ];
+ double param1 = _leParams[ iTo ];
+ gp_XY rangeUV = uv1 - uv0;
for ( size_t i = iFrom; i < iTo; ++i )
{
if ( _eos[i]->Is( _LayerEdge::BLOCKED )) continue;
double param = ( _leParams[i] - param0 ) / ( param1 - param0 );
gp_XY newUV = uv0 + param * rangeUV;
- _eos[i]->_pos.back().SetCoord( newUV.X(), newUV.Y(), 0 );
gp_Pnt newPos = surface->Value( newUV.X(), newUV.Y() );
SMDS_MeshNode* tgtNode = const_cast<SMDS_MeshNode*>( _eos[i]->_nodes.back() );
SMDS_FacePosition* pos = static_cast<SMDS_FacePosition*>( tgtNode->GetPosition() );
pos->SetUParameter( newUV.X() );
pos->SetVParameter( newUV.Y() );
+
+ gp_XYZ newUV0( newUV.X(), newUV.Y(), 0 );
+
+ if ( !_eos[i]->Is( _LayerEdge::SMOOTHED ))
+ {
+ _eos[i]->Set( _LayerEdge::SMOOTHED ); // to check in refine() (IPAL54237)
+ if ( _eos[i]->_pos.size() > 2 )
+ {
+ // modify previous positions to make _LayerEdge less sharply bent
+ vector<gp_XYZ>& uvVec = _eos[i]->_pos;
+ const gp_XYZ uvShift = newUV0 - uvVec.back();
+ const double len2 = ( uvVec.back() - uvVec[ 0 ] ).SquareModulus();
+ int iPrev = uvVec.size() - 2;
+ while ( iPrev > 0 )
+ {
+ double r = ( uvVec[ iPrev ] - uvVec[0] ).SquareModulus() / len2;
+ uvVec[ iPrev ] += uvShift * r;
+ --iPrev;
+ }
+ }
+ }
+ _eos[i]->_pos.back() = newUV0;
}
}
}
SMDS_FacePosition* pos = static_cast<SMDS_FacePosition*>( tgtNode->GetPosition() );
pos->SetUParameter( newUV.X() );
pos->SetVParameter( newUV.Y() );
+
+ _eos[i]->Set( _LayerEdge::SMOOTHED ); // to check in refine() (IPAL54237)
}
}
return true;
// project tgt nodes of extreme _LayerEdge's to the offset segments
// -----------------------------------------------------------------
- if ( e[0]->Is( _LayerEdge::NORMAL_UPDATED )) _iSeg[0] = 0;
- if ( e[1]->Is( _LayerEdge::NORMAL_UPDATED )) _iSeg[1] = _offPoints.size()-2;
+ const int updatedOrBlocked = _LayerEdge::NORMAL_UPDATED | _LayerEdge::BLOCKED;
+ if ( e[0]->Is( updatedOrBlocked )) _iSeg[0] = 0;
+ if ( e[1]->Is( updatedOrBlocked )) _iSeg[1] = _offPoints.size()-2;
gp_Pnt pExtreme[2], pProj[2];
for ( int is2nd = 0; is2nd < 2; ++is2nd )
gp_Vec vDiv1( pExtreme[1], pProj[1] );
double d0 = vDiv0.Magnitude();
double d1 = vDiv1.Magnitude();
- if ( e[0]->_normal * vDiv0.XYZ() < 0 ) e[0]->_len += d0;
- else e[0]->_len -= d0;
- if ( e[1]->_normal * vDiv1.XYZ() < 0 ) e[1]->_len += d1;
- else e[1]->_len -= d1;
+ if ( e[0]->Is( _LayerEdge::BLOCKED )) {
+ if ( e[0]->_normal * vDiv0.XYZ() < 0 ) e[0]->_len += d0;
+ else e[0]->_len -= d0;
+ }
+ if ( e[1]->Is( _LayerEdge::BLOCKED )) {
+ if ( e[1]->_normal * vDiv1.XYZ() < 0 ) e[1]->_len += d1;
+ else e[1]->_len -= d1;
+ }
// ---------------------------------------------------------------------------------
// compute normalized length of the offset segments located between the projections
// divide E to have offset segments with low deflection
BRepAdaptor_Curve c3dAdaptor( E );
- const double curDeflect = 0.1; //0.3; // 0.01; // Curvature deflection
- const double angDeflect = 0.1; //0.2; // 0.09; // Angular deflection
+ const double curDeflect = 0.1; //0.01; // Curvature deflection == |p1p2]*sin(p1p2,p1pM)
+ const double angDeflect = 0.1; //0.09; // Angular deflection == sin(p1pM,pMp2)
GCPnts_TangentialDeflection discret(c3dAdaptor, angDeflect, curDeflect);
if ( discret.NbPoints() <= 2 )
{
const double u0 = c3dAdaptor.FirstParameter();
gp_Pnt p; gp_Vec tangent;
- _offPoints.resize( discret.NbPoints() );
- for ( size_t i = 0; i < _offPoints.size(); i++ )
+ if ( discret.NbPoints() >= (int) _eos.size() + 2 )
+ {
+ _offPoints.resize( discret.NbPoints() );
+ for ( size_t i = 0; i < _offPoints.size(); i++ )
+ {
+ double u = discret.Parameter( i+1 );
+ c3dAdaptor.D1( u, p, tangent );
+ _offPoints[i]._xyz = p.XYZ();
+ _offPoints[i]._edgeDir = tangent.XYZ();
+ _offPoints[i]._param = GCPnts_AbscissaPoint::Length( c3dAdaptor, u0, u ) / _curveLen;
+ }
+ }
+ else
{
- double u = discret.Parameter( i+1 );
- c3dAdaptor.D1( u, p, tangent );
- _offPoints[i]._xyz = p.XYZ();
- _offPoints[i]._edgeDir = tangent.XYZ();
- _offPoints[i]._param = GCPnts_AbscissaPoint::Length( c3dAdaptor, u0, u ) / _curveLen;
+ std::vector< double > params( _eos.size() + 2 );
+
+ params[0] = data.GetHelper().GetNodeU( E, leOnV[0]->_nodes[0] );
+ params.back() = data.GetHelper().GetNodeU( E, leOnV[1]->_nodes[0] );
+ for ( size_t i = 0; i < _eos.size(); i++ )
+ params[i+1] = data.GetHelper().GetNodeU( E, _eos[i]->_nodes[0] );
+
+ if ( params[1] > params[ _eos.size() ] )
+ std::reverse( params.begin() + 1, params.end() - 1 );
+
+ _offPoints.resize( _eos.size() + 2 );
+ for ( size_t i = 0; i < _offPoints.size(); i++ )
+ {
+ const double u = params[i];
+ c3dAdaptor.D1( u, p, tangent );
+ _offPoints[i]._xyz = p.XYZ();
+ _offPoints[i]._edgeDir = tangent.XYZ();
+ _offPoints[i]._param = GCPnts_AbscissaPoint::Length( c3dAdaptor, u0, u ) / _curveLen;
+ }
}
// set _2edges
int iLBO = _offPoints.size() - 2; // last but one
- _leOnV[ 0 ]._normal = getNormalNormal( leOnV[0]->_normal, _edgeDir[0] );
- _leOnV[ 1 ]._normal = getNormalNormal( leOnV[1]->_normal, _edgeDir[1] );
+ if ( leOnV[ 0 ]->Is( _LayerEdge::MULTI_NORMAL ))
+ _leOnV[ 0 ]._normal = getNormalNormal( _eos._edges[1]->_normal, _edgeDir[0] );
+ else
+ _leOnV[ 0 ]._normal = getNormalNormal( leOnV[0]->_normal, _edgeDir[0] );
+ if ( leOnV[ 1 ]->Is( _LayerEdge::MULTI_NORMAL ))
+ _leOnV[ 1 ]._normal = getNormalNormal( _eos._edges.back()->_normal, _edgeDir[1] );
+ else
+ _leOnV[ 1 ]._normal = getNormalNormal( leOnV[1]->_normal, _edgeDir[1] );
_leOnV[ 0 ]._len = 0;
_leOnV[ 1 ]._len = 0;
_leOnV[ 0 ]._lenFactor = _offPoints[1 ]._2edges._edges[1]->_lenFactor;
//================================================================================
/*!
- * \brief set _normal of _leOnV[is2nd] to be normal to the EDGE
+ * \brief return _normal of _leOnV[is2nd] normal to the EDGE
*/
//================================================================================
gp_XYZ norm = edgeDir ^ cross;
double size = norm.Modulus();
+ // if ( size == 0 ) // MULTI_NORMAL _LayerEdge
+ // return gp_XYZ( 1e-100, 1e-100, 1e-100 );
+
return norm / size;
}
// compute new _normals
for ( size_t i = 0; i < intEdgesDist.size(); ++i )
{
- _LayerEdge* edge2 = intEdgesDist[i].first;
- double distWgt = edge1->_len / intEdgesDist[i].second;
+ _LayerEdge* edge2 = intEdgesDist[i].first;
+ double distWgt = edge1->_len / intEdgesDist[i].second;
// if ( edge1->Is( _LayerEdge::BLOCKED ) &&
// edge2->Is( _LayerEdge::BLOCKED )) continue;
if ( edge2->Is( _LayerEdge::MARKED )) continue;
e2neIt->second._maxLen = 0.7 * minIntDist / edge1->_lenFactor;
if ( iter > 0 && sgn1 * sgn2 < 0 && edge1->_cosin < 0 )
e2neIt->second._normal += dir2;
+
e2neIt = edge2newEdge.insert( make_pair( edge2, zeroEdge )).first;
e2neIt->second._normal += distWgt * newNormal;
- e2neIt->second._cosin = edge2->_cosin;
+ if ( Precision::IsInfinite( zeroEdge._maxLen ))
+ {
+ e2neIt->second._cosin = edge2->_cosin;
+ e2neIt->second._maxLen = 1.3 * minIntDist / edge1->_lenFactor;
+ }
if ( iter > 0 && sgn1 * sgn2 < 0 && edge2->_cosin < 0 )
e2neIt->second._normal += dir1;
}
for ( e2neIt = edge2newEdge.begin(); e2neIt != edge2newEdge.end(); ++e2neIt )
{
_LayerEdge* edge = e2neIt->first;
- if ( edge->Is( _LayerEdge::BLOCKED )) continue;
_LayerEdge& newEdge = e2neIt->second;
_EdgesOnShape* eos = data.GetShapeEdges( edge );
+ if ( edge->Is( _LayerEdge::BLOCKED && newEdge._maxLen > edge->_len ))
+ continue;
// Check if a new _normal is OK:
newEdge._normal.Normalize();
gp_XYZ _LayerEdge::PrevCheckPos( _EdgesOnShape* eos ) const
{
- size_t i = Is( NORMAL_UPDATED ) ? _pos.size()-2 : 0;
+ size_t i = Is( NORMAL_UPDATED ) && IsOnFace() ? _pos.size()-2 : 0;
if ( !eos || eos->_sWOL.IsNull() )
return _pos[ i ];
{
_EdgesOnShape* eos = data.GetShapeEdges( neibor );
while ( neibor->_len > neibor->_maxLen &&
- neibor->NbSteps() > 1 )
+ neibor->NbSteps() > 0 )
neibor->InvalidateStep( neibor->NbSteps(), *eos, /*restoreLength=*/true );
neibor->SetNewLength( neibor->_maxLen, *eos, data.GetHelper() );
//neibor->Block( data );
if ( restoreLength )
{
- _len -= ( nXYZ.XYZ() - curXYZ ).Modulus() / _lenFactor;
+ if ( NbSteps() == 0 )
+ _len = 0.;
+ else
+ _len -= ( nXYZ.XYZ() - curXYZ ).Modulus() / _lenFactor;
}
}
}
}
else if ( eos._isRegularSWOL ) // usual SWOL
{
- for ( size_t j = 1; j < edge._pos.size(); ++j )
- segLen[j] = segLen[j-1] + (edge._pos[j-1] - edge._pos[j] ).Modulus();
+ if ( edge.Is( _LayerEdge::SMOOTHED ))
+ {
+ SMESH_NodeXYZ p0( edge._nodes[0] );
+ for ( size_t j = 1; j < edge._pos.size(); ++j )
+ {
+ gp_XYZ pj = surface->Value( edge._pos[j].X(), edge._pos[j].Y() ).XYZ();
+ segLen[j] = ( pj - p0 ) * edge._normal;
+ }
+ }
+ else
+ {
+ for ( size_t j = 1; j < edge._pos.size(); ++j )
+ segLen[j] = segLen[j-1] + (edge._pos[j-1] - edge._pos[j] ).Modulus();
+ }
}
else if ( !surface.IsNull() ) // SWOL surface with singularities
{
faceProj->Perform( p );
if ( !faceProj->IsDone() || faceProj->NbPoints() < 1 )
return setLayerEdgeData( lEdge, u, pcurve, curve, p, reverse, NULL );
- Quantity_Parameter U,V;
+ Standard_Real U,V;
faceProj->LowerDistanceParameters(U,V);
lEdge._normal2D.SetCoord( U - uv.X(), V - uv.Y() );
lEdge._normal2D.Normalize();