- myLastCreatedElems.Clear();
- myLastCreatedNodes.Clear();
-
- int aNbE;
- std::list<double> aPrms;
- TIDSortedElemSet::iterator itElem;
-
- gp_XYZ aGC;
- TopoDS_Edge aTrackEdge;
- TopoDS_Vertex aV1, aV2;
-
- SMDS_ElemIteratorPtr aItE;
- SMDS_NodeIteratorPtr aItN;
- SMDSAbs_ElementType aTypeE;
-
- TNodeOfNodeListMap mapNewNodes;
-
- // 1. Check data
- aNbE = theElements[0].size() + theElements[1].size();
- // nothing to do
- if ( !aNbE )
- return EXTR_NO_ELEMENTS;
-
- // 1.1 Track Pattern
- ASSERT( theTrack );
-
- SMESHDS_Mesh* pMeshDS = theTrack->GetMeshDS();
-
- aItE = pMeshDS->elementsIterator();
- while ( aItE->more() ) {
- const SMDS_MeshElement* pE = aItE->next();
- aTypeE = pE->GetType();
- // Pattern must contain links only
- if ( aTypeE != SMDSAbs_Edge )
- return EXTR_PATH_NOT_EDGE;
- }
-
- list<SMESH_MeshEditor_PathPoint> fullList;
-
- const TopoDS_Shape& aS = theTrack->GetShapeToMesh();
-
- if ( !theTrack->HasShapeToMesh() ) {
- //Mesh without shape
- const SMDS_MeshNode* currentNode = NULL;
- const SMDS_MeshNode* prevNode = theN1;
- std::vector<const SMDS_MeshNode*> aNodesList;
- aNodesList.push_back(theN1);
- int nbEdges = 0, conn=0;
- const SMDS_MeshElement* prevElem = NULL;
- const SMDS_MeshElement* currentElem = NULL;
- int totalNbEdges = theTrack->NbEdges();
- SMDS_ElemIteratorPtr nIt;
-
- //check start node
- if( !theTrack->GetMeshDS()->Contains(theN1) ) {
- return EXTR_BAD_STARTING_NODE;
- }
-
- conn = nbEdgeConnectivity(theN1);
- if( conn != 1 )
- return EXTR_PATH_NOT_EDGE;
-
- aItE = theN1->GetInverseElementIterator();
- prevElem = aItE->next();
- currentElem = prevElem;
- //Get all nodes
- if(totalNbEdges == 1 ) {
- nIt = currentElem->nodesIterator();
- currentNode = static_cast<const SMDS_MeshNode*>(nIt->next());
- if(currentNode == prevNode)
- currentNode = static_cast<const SMDS_MeshNode*>(nIt->next());
- aNodesList.push_back(currentNode);
- } else {
- nIt = currentElem->nodesIterator();
- while( nIt->more() ) {
- currentNode = static_cast<const SMDS_MeshNode*>(nIt->next());
- if(currentNode == prevNode)
- currentNode = static_cast<const SMDS_MeshNode*>(nIt->next());
- aNodesList.push_back(currentNode);
-
- //case of the closed mesh
- if(currentNode == theN1) {
- nbEdges++;
- break;
- }
-
- conn = nbEdgeConnectivity(currentNode);
- if(conn > 2) {
- return EXTR_PATH_NOT_EDGE;
- }else if( conn == 1 && nbEdges > 0 ) {
- //End of the path
- nbEdges++;
- break;
- }else {
- prevNode = currentNode;
- aItE = currentNode->GetInverseElementIterator();
- currentElem = aItE->next();
- if( currentElem == prevElem)
- currentElem = aItE->next();
- nIt = currentElem->nodesIterator();
- prevElem = currentElem;
- nbEdges++;
- }
- }
- }
-
- if(nbEdges != totalNbEdges)
- return EXTR_PATH_NOT_EDGE;
-
- TopTools_SequenceOfShape Edges;
- list< list<SMESH_MeshEditor_PathPoint> > LLPPs;
- int startNid = theN1->GetID();
- for ( size_t i = 1; i < aNodesList.size(); i++ )
- {
- gp_Pnt p1 = SMESH_TNodeXYZ( aNodesList[i-1] );
- gp_Pnt p2 = SMESH_TNodeXYZ( aNodesList[i] );
- TopoDS_Edge e = BRepBuilderAPI_MakeEdge( p1, p2 );
- list<SMESH_MeshEditor_PathPoint> LPP;
- aPrms.clear();
- makeEdgePathPoints(aPrms, e, (aNodesList[i-1]->GetID()==startNid), LPP);
- LLPPs.push_back(LPP);
- if ( aNodesList[i-1]->GetID() == startNid ) startNid = aNodesList[i ]->GetID();
- else startNid = aNodesList[i-1]->GetID();
- }
-
- list< list<SMESH_MeshEditor_PathPoint> >::iterator itLLPP = LLPPs.begin();
- list<SMESH_MeshEditor_PathPoint> firstList = *itLLPP;
- list<SMESH_MeshEditor_PathPoint>::iterator itPP = firstList.begin();
- for(; itPP!=firstList.end(); itPP++) {
- fullList.push_back( *itPP );
- }
-
- SMESH_MeshEditor_PathPoint PP1 = fullList.back();
- SMESH_MeshEditor_PathPoint PP2;
- fullList.pop_back();
- itLLPP++;
- for(; itLLPP!=LLPPs.end(); itLLPP++) {
- list<SMESH_MeshEditor_PathPoint> currList = *itLLPP;
- itPP = currList.begin();
- PP2 = currList.front();
- gp_Dir D1 = PP1.Tangent();
- gp_Dir D2 = PP2.Tangent();
- gp_Dir Dnew( 0.5 * ( D1.XYZ() + D2.XYZ() ));
- PP1.SetTangent(Dnew);
- fullList.push_back(PP1);
- itPP++;
- for(; itPP!=currList.end(); itPP++) {
- fullList.push_back( *itPP );
- }
- PP1 = fullList.back();
- fullList.pop_back();
- }
- fullList.push_back(PP1);
-
- } // Sub-shape for the Pattern must be an Edge or Wire
- else if ( aS.ShapeType() == TopAbs_EDGE )
- {
- aTrackEdge = TopoDS::Edge( aS );
- // the Edge must not be degenerated
- if ( SMESH_Algo::isDegenerated( aTrackEdge ) )
- return EXTR_BAD_PATH_SHAPE;
- TopExp::Vertices( aTrackEdge, aV1, aV2 );
- const SMDS_MeshNode* aN1 = SMESH_Algo::VertexNode( aV1, pMeshDS );
- const SMDS_MeshNode* aN2 = SMESH_Algo::VertexNode( aV2, pMeshDS );
- // starting node must be aN1 or aN2
- if ( !( aN1 == theN1 || aN2 == theN1 ) )
- return EXTR_BAD_STARTING_NODE;
- aItN = pMeshDS->nodesIterator();
- while ( aItN->more() ) {
- const SMDS_MeshNode* pNode = aItN->next();
- if( pNode==aN1 || pNode==aN2 ) continue;
- const SMDS_EdgePosition* pEPos =
- static_cast<const SMDS_EdgePosition*>( pNode->GetPosition() );
- double aT = pEPos->GetUParameter();
- aPrms.push_back( aT );
- }
- //Extrusion_Error err =
- makeEdgePathPoints(aPrms, aTrackEdge, (aN1==theN1), fullList);
- }
- else if( aS.ShapeType() == TopAbs_WIRE ) {
- list< SMESH_subMesh* > LSM;
- TopTools_SequenceOfShape Edges;
- TopExp_Explorer eExp(aS, TopAbs_EDGE);
- for(; eExp.More(); eExp.Next()) {
- TopoDS_Edge E = TopoDS::Edge( eExp.Current() );
- if( SMESH_Algo::isDegenerated(E) ) continue;
- SMESH_subMesh* SM = theTrack->GetSubMesh(E);
- if(SM) {
- LSM.push_back(SM);
- Edges.Append(E);
- }
- }
- list< list<SMESH_MeshEditor_PathPoint> > LLPPs;
- TopoDS_Vertex aVprev;
- TColStd_MapOfInteger UsedNums;
- int NbEdges = Edges.Length();
- int i = 1;
- for(; i<=NbEdges; i++) {
- int k = 0;
- list< SMESH_subMesh* >::iterator itLSM = LSM.begin();
- for(; itLSM!=LSM.end(); itLSM++) {
- k++;
- if(UsedNums.Contains(k)) continue;
- aTrackEdge = TopoDS::Edge( Edges.Value(k) );
- SMESH_subMesh* locTrack = *itLSM;
- SMESHDS_SubMesh* locMeshDS = locTrack->GetSubMeshDS();
- TopExp::Vertices( aTrackEdge, aV1, aV2 );
- bool aN1isOK = false, aN2isOK = false;
- if ( aVprev.IsNull() ) {
- // if previous vertex is not yet defined, it means that we in the beginning of wire
- // and we have to find initial vertex corresponding to starting node theN1
- const SMDS_MeshNode* aN1 = SMESH_Algo::VertexNode( aV1, pMeshDS );
- const SMDS_MeshNode* aN2 = SMESH_Algo::VertexNode( aV2, pMeshDS );
- // starting node must be aN1 or aN2
- aN1isOK = ( aN1 && aN1 == theN1 );
- aN2isOK = ( aN2 && aN2 == theN1 );
- }
- else {
- // we have specified ending vertex of the previous edge on the previous iteration
- // and we have just to check that it corresponds to any vertex in current segment
- aN1isOK = aVprev.IsSame( aV1 );
- aN2isOK = aVprev.IsSame( aV2 );
- }
- if ( !aN1isOK && !aN2isOK ) continue;
- // 2. Collect parameters on the track edge
- aPrms.clear();
- aItN = locMeshDS->GetNodes();
- while ( aItN->more() ) {
- const SMDS_MeshNode* pNode = aItN->next();
- const SMDS_EdgePosition* pEPos =
- static_cast<const SMDS_EdgePosition*>( pNode->GetPosition() );
- double aT = pEPos->GetUParameter();
- aPrms.push_back( aT );
- }
- list<SMESH_MeshEditor_PathPoint> LPP;
- //Extrusion_Error err =
- makeEdgePathPoints(aPrms, aTrackEdge, aN1isOK, LPP);
- LLPPs.push_back(LPP);
- UsedNums.Add(k);
- // update startN for search following egde
- if ( aN1isOK ) aVprev = aV2;
- else aVprev = aV1;
- break;
- }
- }
- list< list<SMESH_MeshEditor_PathPoint> >::iterator itLLPP = LLPPs.begin();
- list<SMESH_MeshEditor_PathPoint>& firstList = *itLLPP;
- fullList.splice( fullList.end(), firstList );
-
- SMESH_MeshEditor_PathPoint PP1 = fullList.back();
- fullList.pop_back();
- itLLPP++;
- for(; itLLPP!=LLPPs.end(); itLLPP++) {
- list<SMESH_MeshEditor_PathPoint>& currList = *itLLPP;
- SMESH_MeshEditor_PathPoint PP2 = currList.front();
- gp_Dir D1 = PP1.Tangent();
- gp_Dir D2 = PP2.Tangent();
- gp_Dir Dnew( D1.XYZ() + D2.XYZ() );
- PP1.SetTangent(Dnew);
- fullList.push_back(PP1);
- fullList.splice( fullList.end(), currList, ++currList.begin(), currList.end() );
- PP1 = fullList.back();
- fullList.pop_back();
- }
- // if wire not closed
- fullList.push_back(PP1);
- // else ???
- }
- else {
- return EXTR_BAD_PATH_SHAPE;
- }
-
- return makeExtrElements(theElements, fullList, theHasAngles, theAngles, theLinearVariation,
- theHasRefPoint, theRefPoint, theMakeGroups);
-}
-
-
-//=======================================================================
-//function : makeEdgePathPoints
-//purpose : auxiliary for ExtrusionAlongTrack
-//=======================================================================
-SMESH_MeshEditor::Extrusion_Error
-SMESH_MeshEditor::makeEdgePathPoints(std::list<double>& aPrms,
- const TopoDS_Edge& aTrackEdge,
- bool FirstIsStart,
- list<SMESH_MeshEditor_PathPoint>& LPP)
-{
- Standard_Real aTx1, aTx2, aL2, aTolVec, aTolVec2;
- aTolVec=1.e-7;
- aTolVec2=aTolVec*aTolVec;
- double aT1, aT2;
- TopoDS_Vertex aV1, aV2;
- TopExp::Vertices( aTrackEdge, aV1, aV2 );
- aT1=BRep_Tool::Parameter( aV1, aTrackEdge );
- aT2=BRep_Tool::Parameter( aV2, aTrackEdge );
- // 2. Collect parameters on the track edge
- aPrms.push_front( aT1 );
- aPrms.push_back( aT2 );
- // sort parameters
- aPrms.sort();
- if( FirstIsStart ) {
- if ( aT1 > aT2 ) {
- aPrms.reverse();
- }
- }
- else {
- if ( aT2 > aT1 ) {
- aPrms.reverse();
- }
- }
- // 3. Path Points
- SMESH_MeshEditor_PathPoint aPP;
- Handle(Geom_Curve) aC3D = BRep_Tool::Curve( aTrackEdge, aTx1, aTx2 );
- std::list<double>::iterator aItD = aPrms.begin();
- for(; aItD != aPrms.end(); ++aItD) {
- double aT = *aItD;
- gp_Pnt aP3D;
- gp_Vec aVec;
- aC3D->D1( aT, aP3D, aVec );
- aL2 = aVec.SquareMagnitude();
- if ( aL2 < aTolVec2 )
- return EXTR_CANT_GET_TANGENT;
- gp_Dir aTgt( FirstIsStart ? aVec : -aVec );
- aPP.SetPnt( aP3D );
- aPP.SetTangent( aTgt );
- aPP.SetParameter( aT );
- LPP.push_back(aPP);
- }
- return EXTR_OK;
-}