Salome HOME
Implement PAL7218: Sweep mesh elements along discretized curve
authorvsr <vsr@opencascade.com>
Mon, 17 Jan 2005 12:48:21 +0000 (12:48 +0000)
committervsr <vsr@opencascade.com>
Mon, 17 Jan 2005 12:48:21 +0000 (12:48 +0000)
Makefile.in
idl/SMESH_Mesh.idl
resources/SMESH_en.xml
resources/mesh_add.png [new file with mode: 0755]
resources/mesh_extrusionpath.png [new file with mode: 0644]
resources/mesh_remove.png [new file with mode: 0755]
src/SMESH/SMESH_MeshEditor.cxx
src/SMESH/SMESH_MeshEditor.hxx

index 1f62bb34444b78ed00fc0b9f19fb1195c762778b..dfbd2629a219fe073b359d930f3a4971f1398649 100644 (file)
@@ -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
index d64d9389f269a7daab7e72e8e35a8a7ad4bd6842..3a70eaf46eb9f59da9bac00bb8e4d41721a7c52a 100644 (file)
@@ -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,
index 91fc253623b30b92757ce3841fa0c9fe70fffed0..0bbbc4597578c079d0240d6c87b269bda6b491ac 100644 (file)
      <popup-item item-id="411" pos-id="" label-id="Cutting of quadrangles" icon-id="mesh_cutquad.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
      <popup-item item-id="412" pos-id="" label-id="Smoothing" icon-id="mesh_smoothing.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
      <popup-item item-id="413" pos-id="" label-id="Extrusion" icon-id="mesh_extrusion.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+     <popup-item item-id="416" pos-id="" label-id="Extrusion along a path" icon-id="mesh_extrusionpath.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
      <popup-item item-id="414" pos-id="" label-id="Revolution" icon-id="mesh_revolution.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
      <popup-item item-id="415" pos-id="" label-id="Pattern mapping" icon-id="mesh_pattern.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
 </menu-item>
      <toolbutton-item item-id="411" label-id="Cutting of quadrangles" icon-id="mesh_cutquad.png" tooltip-id="Cutting of quadrangles" accel-id="" toggle-id="" execute-action=""/>
      <toolbutton-item item-id="412" label-id="Smoothing" icon-id="mesh_smoothing.png" tooltip-id="Smoothing" accel-id="" toggle-id="" execute-action=""/>
      <toolbutton-item item-id="413" label-id="Extrusion" icon-id="mesh_extrusion.png" tooltip-id="Extrusion along a line" accel-id="" toggle-id="" execute-action=""/> 
+     <toolbutton-item item-id="416" label-id="Extrusion along a path" icon-id="mesh_extrusionpath.png" tooltip-id="Extrusion along a path" accel-id="" toggle-id="" execute-action=""/> 
      <toolbutton-item item-id="414" label-id="Revolution" icon-id="mesh_revolution.png" tooltip-id="Revolution around an axis" accel-id="" toggle-id="" execute-action=""/>
      <toolbutton-item item-id="415" label-id="Pattern mapping" icon-id="mesh_pattern.png" tooltip-id="2D and 3D pattern mapping" accel-id="" toggle-id="" execute-action=""/>     
 </toolbar>
diff --git a/resources/mesh_add.png b/resources/mesh_add.png
new file mode 100755 (executable)
index 0000000..2dde69a
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 (file)
index 0000000..47f0aa7
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 (executable)
index 0000000..960f1ac
Binary files /dev/null and b/resources/mesh_remove.png differ
index a934a72abf574db6e51b17617df4b3e8cf0a7921..334d47771873a8dd769dc1e234075ad549bccc8e 100644 (file)
 
 #include <TopTools_ListIteratorOfListOfShape.hxx>
 #include <TopTools_ListOfShape.hxx>
+#include <gp_Dir.hxx>
 #include <gp_Vec.hxx>
 #include <gp_Ax1.hxx>
 #include <gp_Trsf.hxx>
 #include <gp_Lin.hxx>
+#include <gp_XYZ.hxx>
 #include <gp.hxx>
 #include <gp_Pln.hxx>
+#include <BRep_Tool.hxx>
+#include <SMDS_EdgePosition.hxx>
+#include <Geom_Curve.hxx>
+
 
 #include <map>
 
@@ -1937,6 +1943,327 @@ void SMESH_MeshEditor::ExtrusionSweep(set<const SMDS_MeshElement*> & 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<const SMDS_MeshElement*> & theElements,
+                                          SMESH_subMesh* theTrack,
+                                          const SMDS_MeshNode* theN1,
+                                          const bool theHasAngles,
+                                          std::list<double>& 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<double> aPrms;
+  std::list<double>::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<double> 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<const SMDS_EdgePosition*>( 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<SMESH_MeshEditor_PathPoint> 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<const SMDS_MeshNode*>( itN->next() );
+       aX = node->X();
+       aY = node->Y();
+       aZ = node->Z();
+
+       if ( mapNewNodes.find( node ) == mapNewNodes.end() ) {
+         list<const SMDS_MeshNode*> 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<TNodeOfNodeListMapItr> & 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<const SMDS_MeshNode*>( itN->next() );
+      TNodeOfNodeListMap::iterator nIt = mapNewNodes.find( node );
+      if ( nIt == mapNewNodes.end() ) {
+        nIt = mapNewNodes.insert( make_pair( node, list<const SMDS_MeshNode*>() )).first;
+        list<const SMDS_MeshNode*>& 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  : 
index 0104b625730c7497dc59044c1a63aea530148e40..3dc5173f695103f3191ffe410ebc7bab9e8692b9 100644 (file)
@@ -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<const SMDS_MeshElement*> & theElements,
+                          SMESH_subMesh*                      theTrackPattern,
+                          const SMDS_MeshNode*                theNodeStart,
+                          const bool                          theHasAngles,
+                          std::list<double>&                  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<const SMDS_MeshElement*> & 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<const SMDS_MeshNode*> & theNodes,