From: vsr Date: Mon, 17 Jan 2005 12:48:21 +0000 (+0000) Subject: Implement PAL7218: Sweep mesh elements along discretized curve X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=d590247c6415a714d2902485cef8ad5445104e7d;p=modules%2Fsmesh.git Implement PAL7218: Sweep mesh elements along discretized curve --- diff --git a/Makefile.in b/Makefile.in index 1f62bb344..dfbd2629a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -99,6 +99,7 @@ mesh_smoothing.png \ mesh_renumbering_nodes.png \ mesh_renumbering_elements.png \ mesh_extrusion.png \ +mesh_extrusionpath.png \ mesh_revolution.png \ ModuleMesh.png \ mesh_unionGroups.png \ @@ -124,7 +125,9 @@ SMESHCatalog.xml \ flight_solid.brep \ mesh_pattern.png \ pattern_sample_2d.png \ -pattern_sample_3D.png +pattern_sample_3D.png \ +mesh_add.png \ +mesh_remove.png BIN_SCRIPT= \ VERSION diff --git a/idl/SMESH_Mesh.idl b/idl/SMESH_Mesh.idl index d64d9389f..3a70eaf46 100644 --- a/idl/SMESH_Mesh.idl +++ b/idl/SMESH_Mesh.idl @@ -335,6 +335,9 @@ module SMESH long NbNodes() raises (SALOME::SALOME_Exception); + long NbElements() + raises (SALOME::SALOME_Exception); + long NbEdges() raises (SALOME::SALOME_Exception); @@ -365,6 +368,15 @@ module SMESH long NbSubMesh() raises (SALOME::SALOME_Exception); + long_array GetElementsId() + raises (SALOME::SALOME_Exception); + + long_array GetElementsByType( in ElementType theType ) + raises (SALOME::SALOME_Exception); + + long_array GetNodesId() + raises (SALOME::SALOME_Exception); + string Dump(); }; @@ -508,6 +520,24 @@ module SMESH in DirStruct StepVector, in long NbOfSteps); + void ExtrusionAlongPath(in long_array IDsOfElements, + in SMESH_Mesh PathMesh, + in GEOM::GEOM_Object PathShape, + in long NodeStart, + in boolean HasAngles, + in double_array Angles, + in boolean HasRefPoint, + in PointStruct RefPoint); + + void ExtrusionAlongPathObject(in SMESH_IDSource theObject, + in SMESH_Mesh PathMesh, + in GEOM::GEOM_Object PathShape, + in long NodeStart, + in boolean HasAngles, + in double_array Angles, + in boolean HasRefPoint, + in PointStruct RefPoint); + enum MirrorType { POINT, AXIS, PLANE }; void Mirror (in long_array IDsOfElements, diff --git a/resources/SMESH_en.xml b/resources/SMESH_en.xml index 91fc25362..0bbbc4597 100644 --- a/resources/SMESH_en.xml +++ b/resources/SMESH_en.xml @@ -127,6 +127,7 @@ + @@ -464,6 +465,7 @@ + diff --git a/resources/mesh_add.png b/resources/mesh_add.png new file mode 100755 index 000000000..2dde69a72 Binary files /dev/null and b/resources/mesh_add.png differ diff --git a/resources/mesh_extrusionpath.png b/resources/mesh_extrusionpath.png new file mode 100644 index 000000000..47f0aa76a Binary files /dev/null and b/resources/mesh_extrusionpath.png differ diff --git a/resources/mesh_remove.png b/resources/mesh_remove.png new file mode 100755 index 000000000..960f1ac00 Binary files /dev/null and b/resources/mesh_remove.png differ diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx index a934a72ab..334d47771 100644 --- a/src/SMESH/SMESH_MeshEditor.cxx +++ b/src/SMESH/SMESH_MeshEditor.cxx @@ -39,12 +39,18 @@ #include #include +#include #include #include #include #include +#include #include #include +#include +#include +#include + #include @@ -1937,6 +1943,327 @@ void SMESH_MeshEditor::ExtrusionSweep(set & theElems, } +class SMESH_MeshEditor_PathPoint { +public: + SMESH_MeshEditor_PathPoint() { + myPnt.SetCoord(99., 99., 99.); + myTgt.SetCoord(1.,0.,0.); + myAngle=0.; + myPrm=0.; + } + void SetPnt(const gp_Pnt& aP3D){ + myPnt=aP3D; + } + void SetTangent(const gp_Dir& aTgt){ + myTgt=aTgt; + } + void SetAngle(const double& aBeta){ + myAngle=aBeta; + } + void SetParameter(const double& aPrm){ + myPrm=aPrm; + } + const gp_Pnt& Pnt()const{ + return myPnt; + } + const gp_Dir& Tangent()const{ + return myTgt; + } + double Angle()const{ + return myAngle; + } + double Parameter()const{ + return myPrm; + } + +protected: + gp_Pnt myPnt; + gp_Dir myTgt; + double myAngle; + double myPrm; +}; + +//======================================================================= +//function : ExtrusionAlongTrack +//purpose : +//======================================================================= +int SMESH_MeshEditor::ExtrusionAlongTrack (std::set & theElements, + SMESH_subMesh* theTrack, + const SMDS_MeshNode* theN1, + const bool theHasAngles, + std::list& theAngles, + const bool theHasRefPoint, + const gp_Pnt& theRefPoint) +{ + MESSAGE("SMESH_MeshEditor::ExtrusionAlongTrack") + int j, iErr, aNbTP, aNbAngles, aNbE, aNb; + double aT1, aT2, aT, aAngle, aX, aY, aZ; + std::list aPrms; + std::list::iterator aItD; + std::set< const SMDS_MeshElement* >::iterator itElem; + + Standard_Real aTx1, aTx2, aL2, aTolVec, aTolVec2; + gp_Pnt aP3D, aV0; + gp_Vec aVec; + gp_XYZ aGC; + Handle(Geom_Curve) aC3D; + TopoDS_Edge aTrackEdge; + TopoDS_Vertex aV1, aV2; + + SMDS_ElemIteratorPtr aItE; + SMDS_NodeIteratorPtr aItN; + SMDSAbs_ElementType aTypeE; + + TNodeOfNodeListMap mapNewNodes; + TElemOfVecOfNnlmiMap mapElemNewNodes; + TElemOfElemListMap newElemsMap; + + aTolVec=1.e-7; + aTolVec2=aTolVec*aTolVec; + iErr=0; + + // 1. Check data + aNbE=theElements.size(); + if ( !aNbE ) { + iErr = 10; // nothing to do + return iErr; + } + + // 1.1 Track Pattern + ASSERT( theTrack ); + + SMESHDS_SubMesh* pSubMeshDS=theTrack->GetSubMeshDS(); + + if ( !pSubMeshDS->Contains( theN1 ) ) { + iErr = 2; // No match found for start node + return iErr; + } + + aItE = pSubMeshDS->GetElements(); + while ( aItE->more() ) { + const SMDS_MeshElement* pE = aItE->next(); + aTypeE = pE->GetType(); + if ( aTypeE != SMDSAbs_Edge ) { + iErr = 3; // Pattern must contain links only + return iErr; + } + } + + const TopoDS_Shape& aS = theTrack->GetSubShape(); + if ( aS.ShapeType() != TopAbs_EDGE) { + iErr = 3; // Sub shape for the Pattern must be an Edge + return iErr; + aTrackEdge = TopoDS::Edge( aS ); + if ( BRep_Tool::Degenerated( aTrackEdge ) ) { + iErr = 4; // the Edge must not be degenerated + return iErr; + } + } + + TopExp::Vertices( aTrackEdge, aV1, aV2 ); + aT1=BRep_Tool::Parameter( aV1, aTrackEdge ); + aT2=BRep_Tool::Parameter( aV2, aTrackEdge ); + + aItN = myMesh->GetSubMesh( aV1 )->GetSubMeshDS()->GetNodes(); + const SMDS_MeshNode* aN1 = aItN->next(); + + aItN = myMesh->GetSubMesh( aV2 )->GetSubMeshDS()->GetNodes(); + const SMDS_MeshNode* aN2 = aItN->next(); + + if ( !( aN1 == theN1 || aN2 == theN1 ) ) { + iErr = 5; // starting node must be aN1 or aN2 + return iErr; + } + + aNbTP = pSubMeshDS->NbNodes() + 2; + + // 1.2. Angles + vector aAngles( aNbTP ); + + if ( theHasAngles ) { + aNbAngles = theAngles.size(); + if ( aNbTP != aNbAngles ) { + iErr = 6; // number of Angles does not match to the number of track points + return iErr; + } + aItD = theAngles.begin(); + for ( j=0; aItD != aPrms.end(); ++aItD, ++j ) { + aAngle = *aItD; + aAngles[j] = aAngle; + } + } + else { + for ( j=0; j < aNbTP; ++j ) { + aAngles[j] = 0.; + } + } + + // 2. Collect parameters on the track edge + aPrms.push_back( aT1 ); + aPrms.push_back( aT2 ); + + aItN = pSubMeshDS->GetNodes(); + while ( aItN->more() ) { + const SMDS_MeshNode* pNode = aItN->next(); + const SMDS_EdgePosition* pEPos = + static_cast( pNode->GetPosition().get() ); + aT = pEPos->GetUParameter(); + aPrms.push_back( aT ); + } + + // sort parameters + aPrms.sort(); + if ( aN1 == theN1 ) { + if ( aT1 > aT2 ) { + aPrms.reverse(); + } + } + else { + if ( aT2 > aT1 ) { + aPrms.reverse(); + } + } + + // 3. Path Points + SMESH_MeshEditor_PathPoint aPP; + vector aPPs( aNbTP ); + // + aC3D = BRep_Tool::Curve( aTrackEdge, aTx1, aTx2 ); + // + aItD = aPrms.begin(); + for ( j=0; aItD != aPrms.end(); ++aItD, ++j ) { + aT = *aItD; + aC3D->D1( aT, aP3D, aVec ); + aL2 = aVec.SquareMagnitude(); + if ( aL2 < aTolVec2 ) { + iErr = 20; // can not obtain the tangent; + return iErr; + } + gp_Dir aTgt( aVec ); + aAngle = aAngles[j]; + + aPP.SetPnt( aP3D ); + aPP.SetTangent( aTgt ); + aPP.SetAngle( aAngle ); + aPP.SetParameter( aT ); + aPPs[j]=aPP; + } + + // 3. Center of rotation aV0 + aV0 = theRefPoint; + if ( !theHasRefPoint ) { + aNb = 0; + aGC.SetCoord( 0.,0.,0. ); + + itElem = theElements.begin(); + for ( ; itElem != theElements.end(); itElem++ ) { + const SMDS_MeshElement* elem = (*itElem); + + SMDS_ElemIteratorPtr itN = elem->nodesIterator(); + while ( itN->more() ) { + const SMDS_MeshNode* node = static_cast( itN->next() ); + aX = node->X(); + aY = node->Y(); + aZ = node->Z(); + + if ( mapNewNodes.find( node ) == mapNewNodes.end() ) { + list aLNx; + mapNewNodes[node] = aLNx; + // + gp_XYZ aXYZ( aX, aY, aZ ); + aGC += aXYZ; + ++aNb; + } + } + } + aGC /= aNb; + aV0.SetXYZ( aGC ); + } // if (!theHasRefPoint) { + mapNewNodes.clear(); + + // 4. Processing the elements + SMESHDS_Mesh* aMesh = GetMeshDS(); + + for ( itElem = theElements.begin(); itElem != theElements.end(); itElem++ ) { + // check element type + const SMDS_MeshElement* elem = (*itElem); + aTypeE = elem->GetType(); + if ( !elem || ( aTypeE != SMDSAbs_Face && aTypeE != SMDSAbs_Edge ) ) + continue; + + vector & newNodesItVec = mapElemNewNodes[ elem ]; + newNodesItVec.reserve( elem->NbNodes() ); + + // loop on elem nodes + SMDS_ElemIteratorPtr itN = elem->nodesIterator(); + while ( itN->more() ) { + + // check if a node has been already processed + const SMDS_MeshNode* node = + static_cast( itN->next() ); + TNodeOfNodeListMap::iterator nIt = mapNewNodes.find( node ); + if ( nIt == mapNewNodes.end() ) { + nIt = mapNewNodes.insert( make_pair( node, list() )).first; + list& listNewNodes = nIt->second; + + // make new nodes + aX = node->X(); aY = node->Y(); aZ = node->Z(); + + Standard_Real aAngle1x; + gp_Pnt aP0x, aP1x, aPN0, aPN1, aV0x, aV1x; + gp_Ax1 anAx1; + + aV0x = aV0; + aPN0.SetCoord(aX, aY, aZ); + + const SMESH_MeshEditor_PathPoint& aPP0 = aPPs[0]; + aP0x = aPP0.Pnt(); + + for ( j = 1; j < aNbTP; ++j ) { + const SMESH_MeshEditor_PathPoint& aPP1 = aPPs[j]; + aP1x = aPP1.Pnt(); + const gp_Dir& aDT1x = aPP1.Tangent(); + aAngle1x = aPP1.Angle(); + + gp_Trsf aTrsf, aTrsfRot; + // Translation + gp_Vec aV01x( aP0x, aP1x ); + aTrsf.SetTranslation( aV01x ); + + // traslated point + aV1x = aV0x.Transformed( aTrsf ); + aPN1 = aPN0.Transformed( aTrsf ); + + if ( theHasAngles ) { + anAx1.SetLocation( aV1x ); + anAx1.SetDirection( aDT1x ); + aTrsfRot.SetRotation( anAx1, aAngle1x ); + + aPN1 = aPN1.Transformed( aTrsfRot ); + } + + // make new node + aX = aPN1.X(); + aY = aPN1.X(); + aZ = aPN1.X(); + const SMDS_MeshNode* newNode = aMesh->AddNode( aX, aY, aZ ); + listNewNodes.push_back( newNode ); + + aPN0 = aPN1; + aP0x = aP1x; + aV0x = aV1x; + } + } + newNodesItVec.push_back( nIt ); + } + // make new elements + sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem] ); + } + + makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElements ); + return iErr; +} + //======================================================================= //function : Transform //purpose : diff --git a/src/SMESH/SMESH_MeshEditor.hxx b/src/SMESH/SMESH_MeshEditor.hxx index 0104b6257..3dc5173f6 100644 --- a/src/SMESH/SMESH_MeshEditor.hxx +++ b/src/SMESH/SMESH_MeshEditor.hxx @@ -41,6 +41,7 @@ class SMDS_MeshFace; class SMDS_MeshNode; class gp_Ax1; class gp_Vec; +class gp_Pnt; class SMESH_MeshEditor { public: @@ -121,13 +122,21 @@ class SMESH_MeshEditor { // Generate new elements by extrusion of theElements // by theStep by theNbSteps + int ExtrusionAlongTrack (std::set & theElements, + SMESH_subMesh* theTrackPattern, + const SMDS_MeshNode* theNodeStart, + const bool theHasAngles, + std::list& theAngles, + const bool theHasRefPoint, + const gp_Pnt& theRefPoint); + // Generate new elements by extrusion of theElements along path given by theTrackPattern, + // theHasAngles are the rotation angles, base point can be given by theRefPoint void Transform (std::set & theElements, const gp_Trsf& theTrsf, const bool theCopy); // Move or copy theElements applying theTrsf to their nodes - typedef std::list< std::list< const SMDS_MeshNode* > > TListOfListOfNodes; void FindCoincidentNodes (std::set & theNodes,