From d590247c6415a714d2902485cef8ad5445104e7d Mon Sep 17 00:00:00 2001 From: vsr Date: Mon, 17 Jan 2005 12:48:21 +0000 Subject: [PATCH] Implement PAL7218: Sweep mesh elements along discretized curve --- Makefile.in | 5 +- idl/SMESH_Mesh.idl | 30 +++ resources/SMESH_en.xml | 2 + resources/mesh_add.png | Bin 0 -> 459 bytes resources/mesh_extrusionpath.png | Bin 0 -> 389 bytes resources/mesh_remove.png | Bin 0 -> 386 bytes src/SMESH/SMESH_MeshEditor.cxx | 327 +++++++++++++++++++++++++++++++ src/SMESH/SMESH_MeshEditor.hxx | 11 +- 8 files changed, 373 insertions(+), 2 deletions(-) create mode 100755 resources/mesh_add.png create mode 100644 resources/mesh_extrusionpath.png create mode 100755 resources/mesh_remove.png 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 0000000000000000000000000000000000000000..2dde69a72145befc454e6bb1e62d9e448fe66630 GIT binary patch literal 459 zcmV;+0W|)JP)0a!^y zK~#90<&!aM!ax{?pGbzdDRg)5-w;Yup@aDg2jbxF)Ip>;NEZiD@)vXv(uk1y8(iEw zxd>(uydjVdZH~0L#1y*qg>d;k?jGK}_XTp~4fdbw%EMcE1e+jl>o=K2Fn}-&!Gs#M zQou?P4B&7)a5-O)kt_u)gaNVUDd#W^^9FlWHzqdgXh&mW10aNmi!!a`I8&N+M|7rr zX5EqMh360{^%0mlSnKIly(h5Fw6A*Gw=MRAt#^=o-WNEN**emOB`o_xUQSI zWg$dSWSCCdQH8hiXg#)!)S);%hxa`{=^MGgbYWQ*i{*mT@kDqI0sR~%?ymxycTM$6 zRjn!j?>#^5?5ecZgH3>x5*bPSS6?@0MxMies1F#4Ayb&N*@^%F002ovPDHLkV1lA2 B!RY`1 literal 0 HcmV?d00001 diff --git a/resources/mesh_extrusionpath.png b/resources/mesh_extrusionpath.png new file mode 100644 index 0000000000000000000000000000000000000000..47f0aa76a191643105e104da911bf214d4154439 GIT binary patch literal 389 zcmV;00eb$4P) zK~#90rIgW?gdhw>Z{}DHr9e&cfi*!Xw3Gc1b`X(aXWtiUyva*)5EiAN^(-Jyaj#Y2 z4Dyv~g>9w(hIP*xLsq);)J6rhb`>;*e2cZaAsu<#ml0?Nt8(64hoYc*mMyC=yPM1N zwz3W-39(cG5JSd!L*$(#hRh})qshgPvEC>^3Yl2p3hBt${R*p=rCKbO1h{}&Yw5TH zViV)M;Z<#>ki~kV&KphPoL05x{2kV-^irg?H(Q5Ka^47>R^h{L_10R8svz#0znXlzZ1(8SER7>-bDzcjSrA!pTpu1D@k+hHnBg8gKYx7hOb~_afqOW zuqialvUjuV)fre8hMA9l{uvO$l>7VN7))c>{p_St7fLBRj==!hwuLd|(^b literal 0 HcmV?d00001 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,