SMDS_Mesh::_meshList.clear();
MESSAGE(SMDS_Mesh::_meshList.size());
_compute_canceled = false;
- _sm_current = NULL;
//vtkDebugLeaks::SetExitError(0);
}
{
if (_compute_canceled)
return false;
- _sm_current = smToCompute;
+ setCurrentSubMesh( smToCompute );
smToCompute->ComputeStateEngine( computeEvent );
- _sm_current = NULL;
+ setCurrentSubMesh( NULL );
}
// we check all the sub-meshes here and detect if any of them failed to compute
{
if (_compute_canceled)
return false;
- _sm_current = smToCompute;
+ setCurrentSubMesh( smToCompute );
smToCompute->ComputeStateEngine( computeEvent );
- _sm_current = NULL;
+ setCurrentSubMesh( NULL );
if ( aShapesId )
aShapesId->insert( smToCompute->GetId() );
}
if (_compute_canceled)
return false;
- _sm_current = sm;
+ setCurrentSubMesh( sm );
sm->ComputeStateEngine( computeEvent );
- _sm_current = NULL;
+ setCurrentSubMesh( NULL );
if ( aShapesId )
aShapesId->insert( sm->GetId() );
}
const TopoDS_Shape & aShape)
{
_compute_canceled = false;
- _sm_current = NULL;
+ resetCurrentSubMesh();
}
+
//=============================================================================
/*!
* Cancel Compute a mesh
const TopoDS_Shape & aShape)
{
_compute_canceled = true;
- if(_sm_current)
- {
- _sm_current->ComputeStateEngine( SMESH_subMesh::COMPUTE_CANCELED );
- }
+ if ( const SMESH_subMesh* sm = GetCurrentSubMesh() )
+ {
+ const_cast< SMESH_subMesh* >( sm )->ComputeStateEngine( SMESH_subMesh::COMPUTE_CANCELED );
+ }
+ resetCurrentSubMesh();
+}
+
+//================================================================================
+/*!
+ * \brief Returns a sub-mesh being currently computed
+ */
+//================================================================================
+
+const SMESH_subMesh* SMESH_Gen::GetCurrentSubMesh() const
+{
+ return _sm_current.empty() ? 0 : _sm_current.back();
+}
+
+//================================================================================
+/*!
+ * \brief Sets a sub-mesh being currently computed.
+ *
+ * An algorithm can call Compute() for a sub-shape, hence we keep a stack of sub-meshes
+ */
+//================================================================================
+
+void SMESH_Gen::setCurrentSubMesh(SMESH_subMesh* sm)
+{
+ if ( sm )
+ _sm_current.push_back( sm );
+ else
+ _sm_current.pop_back();
+}
+
+void SMESH_Gen::resetCurrentSubMesh()
+{
+ _sm_current.clear();
}
//=============================================================================
void CancelCompute(::SMESH_Mesh & aMesh,
const TopoDS_Shape & aShape);
- const SMESH_subMesh* GetCurrentSubMesh() const { return _sm_current; }
+ const SMESH_subMesh* GetCurrentSubMesh() const;
/*!
* \brief evaluates size of prospective mesh on a shape
// default number of segments
int _nbSegments;
- volatile bool _compute_canceled;
- SMESH_subMesh* _sm_current;
+ void setCurrentSubMesh(SMESH_subMesh* sm);
+ void resetCurrentSubMesh();
+
+ volatile bool _compute_canceled;
+ std::list< SMESH_subMesh* > _sm_current;
};
#endif
SMDSAbs_ElementType highType = SMDSAbs_Edge; // count most complex elements only
while ( eIt->more() && nbInitElems < 2 ) {
const SMDS_MeshElement* e = eIt->next();
- SMDSAbs_ElementType type = e->GetType();
- if ( type == SMDSAbs_Volume || type < highType ) continue;
+ SMDSAbs_ElementType type = e->GetType();
+ if ( type == SMDSAbs_Volume ||
+ type < highType ||
+ !elemSet.count(e))
+ continue;
if ( type > highType ) {
nbInitElems = 0;
- highType = type;
+ highType = type;
}
el = e;
- nbInitElems += elemSet.count(el);
+ ++nbInitElems;
}
if ( nbInitElems == 1 ) {
bool NotCreateEdge = el && el->IsMediumNode(node);
#include <TopoDS_Wire.hxx>
#ifdef _DEBUG_
+//#define _MYDEBUG_
#include "SMESH_File.hxx"
#include "SMESH_Comment.hxx"
#endif
size_t index( const vector< InPoint >& inPoints ) const { return this - &inPoints[0]; }
bool operator==( const InPoint& other ) const { return _a == other._a && _b == other._b; }
+ bool operator==( const TVDVertex* v ) const { return ( Abs( _a - v->x() ) < 1. &&
+ Abs( _b - v->y() ) < 1. ); }
};
// -------------------------------------------------------------------------------------
// check if a TVDEdge begins at my end or ends at my start
inline bool InSegment::isConnected( const TVDEdge* edge )
{
- return ((Abs( edge->vertex0()->x() - _p1->_a ) < 1.&&
- Abs( edge->vertex0()->y() - _p1->_b ) < 1. ) ||
- (Abs( edge->vertex1()->x() - _p0->_a ) < 1.&&
- Abs( edge->vertex1()->y() - _p0->_b ) < 1. ));
+ return (( edge->vertex0() && edge->vertex1() )
+ &&
+ ((Abs( edge->vertex0()->x() - _p1->_a ) < 1.&&
+ Abs( edge->vertex0()->y() - _p1->_b ) < 1. ) ||
+ (Abs( edge->vertex1()->x() - _p0->_a ) < 1.&&
+ Abs( edge->vertex1()->y() - _p0->_b ) < 1. )));
}
// check if a MA TVDEdge is outside of a domain
// }
// -------------------------------------------------------------------------------------
-#ifdef _DEBUG_
+#ifdef _MYDEBUG_
// writes segments into a txt file readable by voronoi_visualizer
void inSegmentsToFile( vector< InSegment>& inSegments)
{
return;
const char* fileName = "/misc/dn25/salome/eap/salome/misc/Code/C++/MAdebug.txt";
SMESH_File file(fileName, false );
+ file.remove();
file.openForWriting();
SMESH_Comment text;
text << "0\n"; // nb points
if ( !edge->vertex1() )
cout << ") -> ( INF, INF";
else
- cout << ") -> (" << edge->vertex1()->x() << ", " << edge->vertex1()->y();
+ cout << ") -> ( " << edge->vertex1()->x() << ", " << edge->vertex1()->y();
cout << ")\t cell=" << edge->cell()
<< " iBnd=" << edge->color()
<< " twin=" << edge->twin()
namespace
{
const int theNoBrachID = 0; // std::numeric_limits<int>::max();
+ double theScale[2]; // scale used in bndSegsToMesh()
// -------------------------------------------------------------------------------------
/*!
//================================================================================
/*!
- * \brief Computes length of of TVDEdge
+ * \brief debug: to visually check found MA edges
+ */
+ //================================================================================
+
+ void bndSegsToMesh( const vector< BndSeg >& bndSegs )
+ {
+#ifdef _MYDEBUG_
+ if ( !getenv("bndSegsToMesh")) return;
+ map< const TVDVertex *, int > v2Node;
+ map< const TVDVertex *, int >::iterator v2n;
+ set< const TVDEdge* > addedEdges;
+
+ const char* fileName = "/misc/dn25/salome/eap/salome/misc/Code/C++/MAedges.py";
+ SMESH_File file(fileName, false );
+ file.remove();
+ file.openForWriting();
+ SMESH_Comment text;
+ text << "import salome, SMESH\n";
+ text << "salome.salome_init()\n";
+ text << "from salome.smesh import smeshBuilder\n";
+ text << "smesh = smeshBuilder.New(salome.myStudy)\n";
+ text << "m=smesh.Mesh()\n";
+ for ( size_t i = 0; i < bndSegs.size(); ++i )
+ {
+ if ( !bndSegs[i]._edge )
+ text << "# " << i << " NULL edge";
+ else if ( !bndSegs[i]._edge->vertex0() ||
+ !bndSegs[i]._edge->vertex1() )
+ text << "# " << i << " INFINITE edge";
+ else if ( addedEdges.insert( bndSegs[i]._edge ).second &&
+ addedEdges.insert( bndSegs[i]._edge->twin() ).second )
+ {
+ v2n = v2Node.insert( make_pair( bndSegs[i]._edge->vertex0(), v2Node.size() + 1 )).first;
+ int n0 = v2n->second;
+ if ( n0 == v2Node.size() )
+ text << "n" << n0 << " = m.AddNode( "
+ << bndSegs[i]._edge->vertex0()->x() / theScale[0] << ", "
+ << bndSegs[i]._edge->vertex0()->y() / theScale[1] << ", 0 )\n";
+
+ v2n = v2Node.insert( make_pair( bndSegs[i]._edge->vertex1(), v2Node.size() + 1 )).first;
+ int n1 = v2n->second;
+ if ( n1 == v2Node.size() )
+ text << "n" << n1 << " = m.AddNode( "
+ << bndSegs[i]._edge->vertex1()->x() / theScale[0] << ", "
+ << bndSegs[i]._edge->vertex1()->y() / theScale[1] << ", 0 )\n";
+
+ text << "e" << i << " = m.AddEdge([ n" << n0 << ", n" << n1 << " ])\n";
+ }
+ }
+ text << "\n";
+ file.write( text.c_str(), text.size() );
+ cout << "Write " << fileName << endl;
+#endif
+ }
+
+ //================================================================================
+ /*!
+ * \brief Computes length of a TVDEdge
*/
//================================================================================
}
}
}
+ // debug
+ theScale[0] = scale[0];
+ theScale[1] = scale[1];
+
return true;
}
continue;
inPntChecked[ pInd ] = true;
- const TVDEdge* edge = // a TVDEdge passing through an end of inSeg
- is2nd ? maEdges.front()->prev() : maEdges.back()->next();
- while ( true )
+ const TVDEdge* maE = is2nd ? maEdges.front() : maEdges.back();
+ if ( inPnt == ( is2nd ? maE->vertex0() : maE->vertex1() ))
+ continue;
+ const TVDEdge* edge = // a secondary TVDEdge connecting inPnt and maE
+ is2nd ? maE->prev() : maE->next();
+ while ( inSeg.isConnected( edge ))
{
if ( edge->is_primary() ) break; // this should not happen
const TVDEdge* edge2 = edge->twin(); // we are in a neighbor cell, add MA edges to inPnt
for ( size_t i = 0; i < bndSegs.size(); ++i )
bndSegs[i].setIndexToEdge( i );
+ bndSegsToMesh( bndSegs ); // debug: visually check found MA edges
+
// Find TVDEdge's of Branches and associate them with bndSegs
size_t i1st = 0;
while ( i1st < bndSegs.size() && !bndSegs[i1st].hasOppositeEdge( noEdgeID ))
++i1st;
- bndSegs[i1st].setBranch( branchID, bndSegs ); // set to the i-th and the opposite bndSeg
+ bndSegs[i1st].setBranch( branchID, bndSegs ); // set to the i-th and to the opposite bndSeg
branchEdges[ branchID ].push_back( bndSegs[i1st]._edge );
for ( size_t i = i1st+1; i < bndSegs.size(); ++i )
endType.insert( make_pair( bndSegs[i]._edge->vertex1(),
SMESH_MAT2d::BE_BRANCH_POINT ));
}
- bndSegs[i].setBranch( branchID, bndSegs ); // set to i-th and the opposite bndSeg
+ bndSegs[i].setBranch( branchID, bndSegs ); // set to i-th and to the opposite bndSeg
if ( bndSegs[i].hasOppositeEdge( noEdgeID ))
branchEdges[ bndSegs[i].branchID() ].push_back( bndSegs[i]._edge );
}
iSeg = iSegEnd;
- } // loop on all bndSegs
+ } // loop on all bndSegs to construct Boundary
// Initialize branches
## Generates new elements by extrusion of the elements with given ids
- # @param IDsOfElements the list of elements ids for extrusion
+ # @param IDsOfElements the list of ids of elements or nodes for extrusion
# @param StepVector vector or DirStruct or 3 vector components, defining
# the direction and value of extrusion for one step (the total extrusion
# length will be NbOfSteps * ||StepVector||)
return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
## Generates new elements by extrusion along the normal to a discretized surface or wire
- # @param Elements elements to extrude - a list including ids, groups, sub-meshes or a mesh
- # Only faces can be extruded so far. Sub-mesh should be a sub-mesh on geom faces.
+ # @param Elements elements to extrude - a list including ids, groups, sub-meshes or a mesh.
+ # Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces.
# @param StepSize length of one extrusion step (the total extrusion
# length will be \a NbOfSteps * \a StepSize ).
# @param NbOfSteps number of extrusion steps.
return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps,
ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim)
- ## Generates new elements by extrusion of the elements which belong to the object
- # @param theObject the object which elements should be processed.
- # It can be a mesh, a sub mesh or a group.
+ ## Generates new elements by extrusion of the elements or nodes which belong to the object
+ # @param theObject the object whose elements or nodes should be processed.
+ # It can be a mesh, a sub-mesh or a group.
# @param StepVector vector or DirStruct or 3 vector components, defining
# the direction and value of extrusion for one step (the total extrusion
# length will be NbOfSteps * ||StepVector||)
# @param NbOfSteps the number of steps
# @param MakeGroups forces the generation of new groups from existing ones
- # @param IsNodes is True if elements to extrude are nodes
+ # @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
def ExtrusionSweepObject(self, theObject, StepVector, NbOfSteps, MakeGroups=False, IsNodes=False):
else : e,f, = theObject,theObject
return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups)
- ## Generates new elements by extrusion of the elements which belong to the object
- # @param theObject object which elements should be processed.
- # It can be a mesh, a sub mesh or a group.
+ ## Generates new elements by extrusion of edges which belong to the object
+ # @param theObject object whose 1D elements should be processed.
+ # It can be a mesh, a sub-mesh or a group.
# @param StepVector vector or DirStruct or 3 vector components, defining
# the direction and value of extrusion for one step (the total extrusion
# length will be NbOfSteps * ||StepVector||)
def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False):
return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups)
- ## Generates new elements by extrusion of the elements which belong to the object
- # @param theObject object which elements should be processed.
- # It can be a mesh, a sub mesh or a group.
+ ## Generates new elements by extrusion of faces which belong to the object
+ # @param theObject object whose 2D elements should be processed.
+ # It can be a mesh, a sub-mesh or a group.
# @param StepVector vector or DirStruct or 3 vector components, defining
# the direction and value of extrusion for one step (the total extrusion
# length will be NbOfSteps * ||StepVector||)
## Generates new elements by extrusion of the given elements
# The path of extrusion must be a meshed edge.
- # @param Base mesh or group, or submesh, or list of ids of elements for extrusion
+ # @param Base mesh or group, or sub-mesh, or list of ids of elements for extrusion
# @param Path - 1D mesh or 1D sub-mesh, along which proceeds the extrusion
# @param NodeStart the start node from Path. Defines the direction of extrusion
# @param HasAngles allows the shape to be rotated around the path
## Generates new elements by extrusion of the elements which belong to the object
# The path of extrusion must be a meshed edge.
- # @param theObject the object which elements should be processed.
+ # @param theObject the object whose elements should be processed.
# It can be a mesh, a sub-mesh or a group.
# @param PathMesh mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
# @param PathShape shape(edge) defines the sub-mesh for the path
if MakeGroups: return gr,er
return er
- ## Generates new elements by extrusion of the elements which belong to the object
+ ## Generates new elements by extrusion of mesh segments which belong to the object
# The path of extrusion must be a meshed edge.
- # @param theObject the object which elements should be processed.
- # It can be a mesh, a sub mesh or a group.
+ # @param theObject the object whose 1D elements should be processed.
+ # It can be a mesh, a sub-mesh or a group.
# @param PathMesh mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
# @param PathShape shape(edge) defines the sub-mesh for the path
# @param NodeStart the first or the last node on the edge. Defines the direction of extrusion
if MakeGroups: return gr,er
return er
- ## Generates new elements by extrusion of the elements which belong to the object
+ ## Generates new elements by extrusion of faces which belong to the object
# The path of extrusion must be a meshed edge.
- # @param theObject the object which elements should be processed.
- # It can be a mesh, a sub mesh or a group.
+ # @param theObject the object whose 2D elements should be processed.
+ # It can be a mesh, a sub-mesh or a group.
# @param PathMesh mesh containing a 1D sub-mesh on the edge, along which the extrusion proceeds
# @param PathShape shape(edge) defines the sub-mesh for the path
# @param NodeStart the first or the last node on the edge. Defines the direction of extrusion
}
list< const SMDS_MeshNode* >& mergeNodes = theSinuFace._nodesToMerge[ existingNode ];
- TIterator u2NPprev = sameU2NP.front(); u2NPprev--;
- TIterator u2NPnext = sameU2NP.back() ; u2NPnext++;
+ TIterator u2NPprev = sameU2NP.front();
+ TIterator u2NPnext = sameU2NP.back() ;
+ if ( u2NPprev->first > 0. ) --u2NPprev;
+ if ( u2NPnext->first < 1. ) ++u2NPprev;
set< int >::iterator edgeID = edgeInds.begin();
for ( ; edgeID != edgeInds.end(); ++edgeID )
if ( getSinuousEdges( helper, sinuFace ))
{
- _progress = 0.2;
+ _progress = 0.4;
double minSegLen = getMinSegLen( helper, sinuFace._sinuEdges );
SMESH_MAT2d::MedialAxis ma( F, sinuFace._sinuEdges, minSegLen, /*ignoreCorners=*/true );
if ( ! divideMA( helper, ma, sinuFace, _regular1D, minSegLen, maParams ))
return error(COMPERR_BAD_SHAPE);
- _progress = 0.4;
+ _progress = 0.8;
if ( _hyp2D )
_regular1D->SetRadialDistribution( _hyp2D );
!computeShortEdges( helper, sinuFace._shortSide[1], _regular1D, _hyp2D, 1 ))
return error("Failed to mesh short edges");
- _progress = 0.6;
+ _progress = 0.85;
if ( !computeSinuEdges( helper, minSegLen, ma, maParams, sinuFace, _regular1D ))
return error("Failed to mesh sinuous edges");
- _progress = 0.8;
+ _progress = 0.9;
bool ok = computeQuads( helper, sinuFace._quad );