From ed456586bfb1411c5bff73b221658766689a6253 Mon Sep 17 00:00:00 2001 From: admin Date: Fri, 17 Dec 2004 11:07:35 +0000 Subject: [PATCH] Merge with OCC-V2_1_0_deb --- Makefile.in | 2 + resources/SMESH_en.xml | 12 +- resources/advanced_mesh_info.png | Bin 0 -> 372 bytes resources/standard_mesh_info.png | Bin 0 -> 355 bytes src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx | 8 +- src/SMESH/Makefile.in | 10 +- src/SMESH/SMESH_1D_Algo.cxx | 1 + src/SMESH/SMESH_2D_Algo.cxx | 1 + src/SMESH/SMESH_3D_Algo.cxx | 1 + src/SMESH/SMESH_Block.cxx | 1019 +++++++++++++++ src/SMESH/SMESH_Block.hxx | 209 +++ src/SMESH/SMESH_Gen.cxx | 33 +- src/SMESH/SMESH_Hypothesis.cxx | 1 + src/SMESH/SMESH_Mesh.cxx | 327 ++++- src/SMESH/SMESH_Mesh.hxx | 40 +- src/SMESH/SMESH_Pattern.cxx | 1130 +---------------- src/SMESH/SMESH_Pattern.hxx | 1 - src/SMESH/SMESH_subMesh.cxx | 107 +- src/SMESH/SMESH_subMesh.hxx | 5 +- src/SMESHGUI/Makefile.in | 2 + src/SMESHGUI/SMESHGUI.cxx | 75 +- src/SMESHGUI/SMESHGUI_EditHypothesesDlg.cxx | 3 +- src/SMESHGUI/SMESHGUI_MeshInfosDlg.cxx | 2 + src/SMESHGUI/SMESHGUI_RotationDlg.cxx | 3 + .../SMESHGUI_StandardMeshInfosDlg.cxx | 448 +++++++ src/SMESHGUI/SMESHGUI_StandardMeshInfosDlg.h | 83 ++ src/SMESHGUI/SMESHGUI_SymmetryDlg.cxx | 3 + src/SMESHGUI/SMESHGUI_TranslationDlg.cxx | 3 + src/SMESHGUI/SMESH_msg_en.po | 12 +- src/SMESH_I/Makefile.in | 3 +- src/SMESH_I/SMESH.hxx | 56 + src/SMESH_I/SMESH_Gen_i_1.cxx | 24 +- src/SMESH_I/SMESH_MEDFamily_i.hxx | 14 +- src/SMESH_I/SMESH_MEDMesh_i.hxx | 4 +- src/SMESH_I/SMESH_MeshEditor_i.cxx | 6 +- src/SMESH_SWIG/Makefile.in | 6 + src/SMESH_SWIG/SMESH_GroupFromGeom2.py | 53 + src/SMESH_SWIG/SMESH_Sphere.py | 107 ++ src/SMESH_SWIG/SMESH_box.py | 73 ++ src/SMESH_SWIG/SMESH_demo_hexa2_upd.py | 210 +++ src/SMESH_SWIG/SMESH_hexaedre.py | 148 +++ src/SMESH_SWIG/meshpy.py | 25 + src/StdMeshers/Makefile.in | 5 +- src/StdMeshers/StdMeshers_Hexa_3D.cxx | 128 +- src/StdMeshers/StdMeshers_Penta_3D.cxx | 1106 ++++++++++++++++ src/StdMeshers/StdMeshers_Penta_3D.hxx | 225 ++++ src/StdMeshers/StdMeshers_Regular_1D.cxx | 188 +-- src/StdMeshers/StdMeshers_Regular_1D.hxx | 12 +- 48 files changed, 4533 insertions(+), 1401 deletions(-) create mode 100644 resources/advanced_mesh_info.png create mode 100644 resources/standard_mesh_info.png create mode 100644 src/SMESH/SMESH_Block.cxx create mode 100644 src/SMESH/SMESH_Block.hxx create mode 100644 src/SMESHGUI/SMESHGUI_StandardMeshInfosDlg.cxx create mode 100644 src/SMESHGUI/SMESHGUI_StandardMeshInfosDlg.h create mode 100644 src/SMESH_I/SMESH.hxx create mode 100755 src/SMESH_SWIG/SMESH_GroupFromGeom2.py create mode 100644 src/SMESH_SWIG/SMESH_Sphere.py create mode 100755 src/SMESH_SWIG/SMESH_box.py create mode 100755 src/SMESH_SWIG/SMESH_demo_hexa2_upd.py create mode 100755 src/SMESH_SWIG/SMESH_hexaedre.py create mode 100644 src/StdMeshers/StdMeshers_Penta_3D.cxx create mode 100644 src/StdMeshers/StdMeshers_Penta_3D.hxx diff --git a/Makefile.in b/Makefile.in index cae80c162..7b95934ee 100644 --- a/Makefile.in +++ b/Makefile.in @@ -38,6 +38,8 @@ mesh_hypo_length.png \ mesh_hypo_segment.png \ mesh_hypo_volume.png \ mesh_info.png \ +advanced_mesh_info.png \ +standard_mesh_info.png \ mesh_init.png \ mesh_length.png \ mesh_free_edges.png \ diff --git a/resources/SMESH_en.xml b/resources/SMESH_en.xml index 0fe9cf4e3..b574a7f2f 100644 --- a/resources/SMESH_en.xml +++ b/resources/SMESH_en.xml @@ -67,7 +67,8 @@ - + + @@ -163,7 +164,8 @@ - + + @@ -211,7 +213,8 @@ - + + @@ -356,7 +359,8 @@ - + + diff --git a/resources/advanced_mesh_info.png b/resources/advanced_mesh_info.png new file mode 100644 index 0000000000000000000000000000000000000000..01eaea2678cc032f562a6ff949634bb47f9a07e1 GIT binary patch literal 372 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE-VTavfC3&Vd9T(EcfWS|IVfk$L9 z0|U1p2s75F#7_hYvX^-Jy0Ty4mgA6DsPdY1ih+TV(bL5-q+-t6DZ6=F3{)eU_hKe5!w`vrw$iCz zH+{OaAX9o-hl9(BeKW1twF<%`pDc~!-&NG@^O!|8TgAhMFFjq)rO2{}IcSN368{G# zfkl_)cJWpAxmmuQ-ZhVDJNp^cBUjyT{SjrW&AoVCZ2uvT`KJ!-F}XKIo^ki7b$gSK zz0y0f^#4+Z7q4^g%Q1hx)X@F7boy3z&F`icLaUD--@5n6l-T17A9mQrlsx|`(@rg-Ah&~qbJAIlNn3bsxYn=!7I{qkM#2JM P_%L|7`njxgN@xNA(p-;G literal 0 HcmV?d00001 diff --git a/resources/standard_mesh_info.png b/resources/standard_mesh_info.png new file mode 100644 index 0000000000000000000000000000000000000000..060008742e9813ab3d8d54be66de7937f353d382 GIT binary patch literal 355 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE-VTavfC3&Vd9T(EcfWS|IVfk$L9 z0|U1p2s75F#7_hYvX^-Jy0Ty4mgA7unl-=p3Q*{Sr;B4q#hkrU_VP9x2(->u7EkXy zr0QM4HAQcY2+MB;t{X?Z10p_gOlNcdBk9xf$t!tZb-BMC4!^CGqq=ywKBS3j3^P6 EPS; - anIsYDimension = (aBounds[3] - aBounds[2]) > EPS; - anIsZDimension = (aBounds[5] - aBounds[4]) > EPS; + anIsXDimension = (aBounds[1] - aBounds[0]) + abs(aBounds[1]) + abs(aBounds[0]) > EPS; + anIsYDimension = (aBounds[3] - aBounds[2]) + abs(aBounds[3]) + abs(aBounds[2]) > EPS; + anIsZDimension = (aBounds[5] - aBounds[4]) + abs(aBounds[5]) + abs(aBounds[4]) > EPS; aMeshDimension = anIsXDimension + anIsYDimension + anIsZDimension; if(!aMeshDimension) diff --git a/src/SMESH/Makefile.in b/src/SMESH/Makefile.in index 9d31f6282..81c62ca98 100644 --- a/src/SMESH/Makefile.in +++ b/src/SMESH/Makefile.in @@ -45,6 +45,7 @@ EXPORT_HEADERS= \ SMESH_3D_Algo.hxx \ SMESH_Group.hxx \ SMESH_MeshEditor.hxx \ + SMESH_Block.hxx \ SMESH_Pattern.hxx EXPORT_PYSCRIPTS = @@ -61,6 +62,7 @@ LIB_SRC = SMESH_Gen.cxx SMESH_Mesh.cxx SMESH_subMesh.cxx \ SMESH_3D_Algo.cxx \ SMESH_Group.cxx \ SMESH_MeshEditor.cxx \ + SMESH_Block.cxx \ SMESH_Pattern.cxx LIB_SERVER_IDL = @@ -73,10 +75,10 @@ BIN_SRC = # additionnal information to compile and link file CPPFLAGS+= $(OCC_INCLUDES) $(MED2_INCLUDES) $(HDF5_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome \ - $(BOOST_CPPFLAGS) -CXXFLAGS+= $(OCC_CXXFLAGS) $(MED2_INCLUDES) $(HDF5_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome - -LDFLAGS+= -L${KERNEL_ROOT_DIR}/lib/salome -lSMESHDS -lMeshDriverDAT -lMeshDriverSTL -lMeshDriverMED -lMeshDriverUNV + -I${GEOM_ROOT_DIR}/include/salome $(BOOST_CPPFLAGS) +CXXFLAGS+= $(OCC_CXXFLAGS) $(MED2_INCLUDES) $(HDF5_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome \ + -I${GEOM_ROOT_DIR}/include/salome +LDFLAGS+= -L${KERNEL_ROOT_DIR}/lib/salome -L${GEOM_ROOT_DIR}/lib/salome -lNMTTools -lSMESHDS -lMeshDriverDAT -lMeshDriverSTL -lMeshDriverMED -lMeshDriverUNV @CONCLUDE@ diff --git a/src/SMESH/SMESH_1D_Algo.cxx b/src/SMESH/SMESH_1D_Algo.cxx index 846f28fb0..37567a536 100644 --- a/src/SMESH/SMESH_1D_Algo.cxx +++ b/src/SMESH/SMESH_1D_Algo.cxx @@ -29,6 +29,7 @@ using namespace std; #include "SMESH_1D_Algo.hxx" #include "SMESH_Gen.hxx" +#include "SMESH_subMesh.hxx" //============================================================================= /*! diff --git a/src/SMESH/SMESH_2D_Algo.cxx b/src/SMESH/SMESH_2D_Algo.cxx index c84a35398..d1084f7d4 100644 --- a/src/SMESH/SMESH_2D_Algo.cxx +++ b/src/SMESH/SMESH_2D_Algo.cxx @@ -29,6 +29,7 @@ using namespace std; #include "SMESH_2D_Algo.hxx" #include "SMESH_Gen.hxx" +#include "SMESH_subMesh.hxx" #include "utilities.h" diff --git a/src/SMESH/SMESH_3D_Algo.cxx b/src/SMESH/SMESH_3D_Algo.cxx index ce35f66d4..d42680f62 100644 --- a/src/SMESH/SMESH_3D_Algo.cxx +++ b/src/SMESH/SMESH_3D_Algo.cxx @@ -29,6 +29,7 @@ using namespace std; #include "SMESH_3D_Algo.hxx" #include "SMESH_Gen.hxx" +#include "SMESH_subMesh.hxx" #include "utilities.h" diff --git a/src/SMESH/SMESH_Block.cxx b/src/SMESH/SMESH_Block.cxx new file mode 100644 index 000000000..6550a81ea --- /dev/null +++ b/src/SMESH/SMESH_Block.cxx @@ -0,0 +1,1019 @@ +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org + +// File : SMESH_Pattern.hxx +// Created : Mon Aug 2 10:30:00 2004 +// Author : Edward AGAPOV (eap) + +#include "SMESH_Block.hxx" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "utilities.h" + +#include + +using namespace std; + +#define SQRT_FUNC 1 + +//======================================================================= +//function : SMESH_Block::TEdge::GetU +//purpose : +//======================================================================= + +double SMESH_Block::TEdge::GetU( const gp_XYZ& theParams ) const +{ + double u = theParams.Coord( myCoordInd ); + return ( 1 - u ) * myFirst + u * myLast; +} + +//======================================================================= +//function : SMESH_Block::TEdge::Point +//purpose : +//======================================================================= + +gp_XYZ SMESH_Block::TEdge::Point( const gp_XYZ& theParams ) const +{ + gp_XYZ p = myC3d->Value( GetU( theParams )).XYZ(); + if ( myTrsf.Form() != gp_Identity ) + myTrsf.Transforms( p ); + return p; +} + +//======================================================================= +//function : SMESH_Block::TFace::GetUV +//purpose : +//======================================================================= + +gp_XY SMESH_Block::TFace::GetUV( const gp_XYZ& theParams ) const +{ + gp_XY uv(0.,0.); + double dU = theParams.Coord( GetUInd() ); + double dV = theParams.Coord( GetVInd() ); + for ( int iE = 0; iE < 4; iE++ ) // loop on 4 edges + { + double Ecoef = 0, Vcoef = 0; + switch ( iE ) { + case 0: + Ecoef = ( 1 - dV ); // u0 + Vcoef = ( 1 - dU ) * ( 1 - dV ); break; // 00 + case 1: + Ecoef = dV; // u1 + Vcoef = dU * ( 1 - dV ); break; // 10 + case 2: + Ecoef = ( 1 - dU ); // 0v + Vcoef = dU * dV ; break; // 11 + case 3: + Ecoef = dU ; // 1v + Vcoef = ( 1 - dU ) * dV ; break; // 01 + default:; + } + // edge addition + double u = theParams.Coord( myCoordInd[ iE ] ); + u = ( 1 - u ) * myFirst[ iE ] + u * myLast[ iE ]; + uv += Ecoef * myC2d[ iE ]->Value( u ).XY(); + // corner addition + uv -= Vcoef * myCorner[ iE ]; + } + return uv; +} + +//======================================================================= +//function : SMESH_Block::TFace::Point +//purpose : +//======================================================================= + +gp_XYZ SMESH_Block::TFace::Point( const gp_XYZ& theParams ) const +{ + gp_XY uv = GetUV( theParams ); + gp_XYZ p = myS->Value( uv.X(), uv.Y() ).XYZ(); + if ( myTrsf.Form() != gp_Identity ) + myTrsf.Transforms( p ); + return p; +} + +//======================================================================= +//function : GetShapeCoef +//purpose : +//======================================================================= + +double* SMESH_Block::GetShapeCoef (const int theShapeID) +{ + static double shapeCoef[][3] = { + // V000, V100, V010, V110 + { -1,-1,-1 }, { 1,-1,-1 }, { -1, 1,-1 }, { 1, 1,-1 }, + // V001, V101, V011, V111, + { -1,-1, 1 }, { 1,-1, 1 }, { -1, 1, 1 }, { 1, 1, 1 }, + // Ex00, Ex10, Ex01, Ex11, + { 0,-1,-1 }, { 0, 1,-1 }, { 0,-1, 1 }, { 0, 1, 1 }, + // E0y0, E1y0, E0y1, E1y1, + { -1, 0,-1 }, { 1, 0,-1 }, { -1, 0, 1 }, { 1, 0, 1 }, + // E00z, E10z, E01z, E11z, + { -1,-1, 0 }, { 1,-1, 0 }, { -1, 1, 0 }, { 1, 1, 0 }, + // Fxy0, Fxy1, Fx0z, Fx1z, F0yz, F1yz, + { 0, 0,-1 }, { 0, 0, 1 }, { 0,-1, 0 }, { 0, 1, 0 }, { -1, 0, 0 }, { 1, 0, 0 }, + // ID_Shell + { 0, 0, 0 } + }; + if ( theShapeID < ID_V000 || theShapeID > ID_F1yz ) + return shapeCoef[ ID_Shell - 1 ]; + + return shapeCoef[ theShapeID - 1 ]; +} + +//======================================================================= +//function : ShellPoint +//purpose : return coordinates of a point in shell +//======================================================================= + +bool SMESH_Block::ShellPoint( const gp_XYZ& theParams, gp_XYZ& thePoint ) const +{ + thePoint.SetCoord( 0., 0., 0. ); + for ( int shapeID = ID_V000; shapeID < ID_Shell; shapeID++ ) + { + // coef + double* coefs = GetShapeCoef( shapeID ); + double k = 1; + for ( int iCoef = 0; iCoef < 3; iCoef++ ) { + if ( coefs[ iCoef ] != 0 ) { + if ( coefs[ iCoef ] < 0 ) + k *= ( 1. - theParams.Coord( iCoef + 1 )); + else + k *= theParams.Coord( iCoef + 1 ); + } + } + // point on a shape + gp_XYZ Ps; + if ( shapeID < ID_Ex00 ) // vertex + VertexPoint( shapeID, Ps ); + else if ( shapeID < ID_Fxy0 ) { // edge + EdgePoint( shapeID, theParams, Ps ); + k = -k; + } else // face + FacePoint( shapeID, theParams, Ps ); + + thePoint += k * Ps; + } + return true; +} + +//======================================================================= +//function : NbVariables +//purpose : +//======================================================================= + +Standard_Integer SMESH_Block::NbVariables() const +{ + return 3; +} + +//======================================================================= +//function : NbEquations +//purpose : +//======================================================================= + +Standard_Integer SMESH_Block::NbEquations() const +{ + return 1; +} + +//======================================================================= +//function : Value +//purpose : +//======================================================================= + +Standard_Boolean SMESH_Block::Value(const math_Vector& theXYZ, math_Vector& theFxyz) +{ + gp_XYZ P, params( theXYZ(1), theXYZ(2), theXYZ(3) ); + if ( params.IsEqual( myParam, DBL_MIN )) { // same param + theFxyz( 1 ) = myValues[ 0 ]; + } + else { + ShellPoint( params, P ); + gp_Vec dP( P - myPoint ); + theFxyz(1) = SQRT_FUNC ? dP.SquareMagnitude() : dP.Magnitude(); + } + return true; +} + +//======================================================================= +//function : Derivatives +//purpose : +//======================================================================= + +Standard_Boolean SMESH_Block::Derivatives(const math_Vector& XYZ,math_Matrix& Df) +{ + MESSAGE( "SMESH_Block::Derivatives()"); + math_Vector F(1,3); + return Values(XYZ,F,Df); +} + +//======================================================================= +//function : Values +//purpose : +//======================================================================= + +Standard_Boolean SMESH_Block::Values(const math_Vector& theXYZ, + math_Vector& theFxyz, + math_Matrix& theDf) +{ +// MESSAGE( endl<<"SMESH_Block::Values( "< DBL_MIN ) + dPi /= mag; + drv[ iP - 1 ] = dPi; + } + for ( int iP = 0; iP < 3; iP++ ) { + if ( iP == myFaceIndex ) + theDf( 1, iP + 1 ) = myFaceParam; + else { + // like IntAna_IntConicQuad::Perform (const gp_Lin& L, const gp_Pln& P) + // where L is (P -> myPoint), P is defined by the 2 other derivative direction + int iPrev = ( iP ? iP - 1 : 2 ); + int iNext = ( iP == 2 ? 0 : iP + 1 ); + gp_Vec plnNorm = drv[ iPrev ].Crossed( drv [ iNext ] ); + double Direc = plnNorm * drv[ iP ]; + if ( Abs(Direc) <= DBL_MIN ) + theDf( 1, iP + 1 ) = dP * drv[ iP ]; + else { + double Dis = plnNorm * P - plnNorm * myPoint; + theDf( 1, iP + 1 ) = Dis/Direc; + } + } + } + //myNbIterations +=3; // how many time call ShellPoint() + + // store better values + myParam = params; + myValues[0]= theFxyz(1); + myValues[1]= theDf(1,1); + myValues[2]= theDf(1,2); + myValues[3]= theDf(1,3); + +// SCRUTE( theFxyz(1) ); +// SCRUTE( theDf( 1,1 )); +// SCRUTE( theDf( 1,2 )); +// SCRUTE( theDf( 1,3 )); + } + + return true; +} + +//======================================================================= +//function : ComputeParameters +//purpose : compute point parameters in the block +//======================================================================= + +bool SMESH_Block::ComputeParameters(const gp_Pnt& thePoint, + gp_XYZ& theParams, + const int theShapeID) +{ +// MESSAGE( endl<<"SMESH_Block::ComputeParameters( " +// < zero ) { + par = v0P.Dot( v01 ) / len2; + if ( par < 0 || par > 1 ) { + needGrid = true; + break; + } + } + start( iParam ) += par; + } + start( iParam ) /= 4.; + } + if ( needGrid ) { + // compute nodes of 3 x 3 x 3 grid + int iNode = 0; + for ( double x = 0.25; x < 0.9; x += 0.25 ) + for ( double y = 0.25; y < 0.9; y += 0.25 ) + for ( double z = 0.25; z < 0.9; z += 0.25 ) { + TxyzPair & prmPtn = my3x3x3GridNodes[ iNode++ ]; + prmPtn.first.SetCoord( x, y, z ); + ShellPoint( prmPtn.first, prmPtn.second ); + } + myGridComputed = true; + } + } + if ( myGridComputed ) { + double minDist = DBL_MAX; + gp_XYZ* bestParam = 0; + for ( int iNode = 0; iNode < 27; iNode++ ) { + TxyzPair & prmPtn = my3x3x3GridNodes[ iNode ]; + double dist = ( thePoint.XYZ() - prmPtn.second ).SquareModulus(); + if ( dist < minDist ) { + minDist = dist; + bestParam = & prmPtn.first; + } + } + start( 1 ) = bestParam->X(); + start( 2 ) = bestParam->Y(); + start( 3 ) = bestParam->Z(); + } + + int myFaceIndex = -1; + if ( isOnFace ) { + // put a point on the face + for ( int iCoord = 0; iCoord < 3; iCoord++ ) + if ( coef[ iCoord ] ) { + myFaceIndex = iCoord; + myFaceParam = ( coef[ myFaceIndex ] < 0.5 ) ? 0.0 : 1.0; + start( iCoord + 1 ) = myFaceParam; + } + } + math_Vector low ( 1, 3, 0.0 ); + math_Vector up ( 1, 3, 1.0 ); + math_Vector tol ( 1, 3, 1e-4 ); + math_FunctionSetRoot paramSearch( *this, tol ); + + int nbLoops = 0; + while ( myValues[0] > 1e-1 && nbLoops++ < 10 ) { + paramSearch.Perform ( *this, start, low, up ); + if ( !paramSearch.IsDone() ) { + //MESSAGE( " !paramSearch.IsDone() " ); + } + else { + //MESSAGE( " NB ITERATIONS: " << paramSearch.NbIterations() ); + } + start( 1 ) = myParam.X(); + start( 2 ) = myParam.Y(); + start( 3 ) = myParam.Z(); + //MESSAGE( "Distance: " << ( SQRT_FUNC ? sqrt(myValues[0]) : myValues[0] )); + } +// MESSAGE( endl << myParam.X() << " " << myParam.Y() << " " << myParam.Z() << endl); +// mySumDist += myValues[0]; +// MESSAGE( " TOTAL NB ITERATIONS: " << myNbIterations << +// " DIST: " << ( SQRT_FUNC ? sqrt(mySumDist) : mySumDist )); + + + theParams = myParam; + + return true; +} + +//======================================================================= +//function : GetStateNumber +//purpose : +//======================================================================= + +Standard_Integer SMESH_Block::GetStateNumber () +{ +// MESSAGE( endl<<"SMESH_Block::GetStateNumber( "< 26 || id < 0 ) { + MESSAGE( "GetShapeIDByParams() = " << id + <<" "<< theCoord.X() <<" "<< theCoord.Y() <<" "<< theCoord.Z() ); + } + + return id + 1; // shape ids start at 1 +} + + +//======================================================================= +//function : getOrderedEdges +//purpose : return nb wires and a list of oredered edges +//======================================================================= + +static int getOrderedEdges (const TopoDS_Face& theFace, + const TopoDS_Vertex& theFirstVertex, + list< TopoDS_Edge >& theEdges, + list< int > & theNbVertexInWires) +{ + // put wires in a list, so that an outer wire comes first + list aWireList; + TopoDS_Wire anOuterWire = BRepTools::OuterWire( theFace ); + aWireList.push_back( anOuterWire ); + for ( TopoDS_Iterator wIt (theFace); wIt.More(); wIt.Next() ) + if ( !anOuterWire.IsSame( wIt.Value() )) + aWireList.push_back( TopoDS::Wire( wIt.Value() )); + + // loop on edges of wires + theNbVertexInWires.clear(); + list::iterator wlIt = aWireList.begin(); + for ( ; wlIt != aWireList.end(); wlIt++ ) + { + int iE; + BRepTools_WireExplorer wExp( *wlIt, theFace ); + for ( iE = 0; wExp.More(); wExp.Next(), iE++ ) + { + TopoDS_Edge edge = wExp.Current(); + edge = TopoDS::Edge( edge.Oriented( wExp.Orientation() )); + theEdges.push_back( edge ); + } + theNbVertexInWires.push_back( iE ); + iE = 0; + if ( wlIt == aWireList.begin() && theEdges.size() > 1 ) { // the outer wire + // orient closed edges + list< TopoDS_Edge >::iterator eIt, eIt2; + for ( eIt = theEdges.begin(); eIt != theEdges.end(); eIt++ ) + { + TopoDS_Edge& edge = *eIt; + if ( TopExp::FirstVertex( edge ).IsSame( TopExp::LastVertex( edge ) )) + { + eIt2 = eIt; + bool isNext = ( eIt2 == theEdges.begin() ); + TopoDS_Edge edge2 = isNext ? *(++eIt2) : *(--eIt2); + double f1,l1,f2,l2; + Handle(Geom2d_Curve) c1 = BRep_Tool::CurveOnSurface( edge, theFace, f1,l1 ); + Handle(Geom2d_Curve) c2 = BRep_Tool::CurveOnSurface( edge2, theFace, f2,l2 ); + gp_Pnt2d pf = c1->Value( edge.Orientation() == TopAbs_FORWARD ? f1 : l1 ); + gp_Pnt2d pl = c1->Value( edge.Orientation() == TopAbs_FORWARD ? l1 : f1 ); + bool isFirst = ( edge2.Orientation() == TopAbs_FORWARD ? isNext : !isNext ); + gp_Pnt2d p2 = c2->Value( isFirst ? f2 : l2 ); + isFirst = ( p2.SquareDistance( pf ) < p2.SquareDistance( pl )); + if ( isNext ? isFirst : !isFirst ) + edge.Reverse(); + } + } + // rotate theEdges until it begins from theFirstVertex + if ( ! theFirstVertex.IsNull() ) + while ( !theFirstVertex.IsSame( TopExp::FirstVertex( theEdges.front(), true ))) + { + theEdges.splice(theEdges.end(), theEdges, + theEdges.begin(), ++ theEdges.begin()); + if ( iE++ > theNbVertexInWires.back() ) + break; // break infinite loop + } + } + } + + return aWireList.size(); +} + +//======================================================================= +//function : LoadBlockShapes +//purpose : add sub-shapes of theBlock to theShapeIDMap so that they get +// IDs acoording to enum TShapeID +//======================================================================= + +bool SMESH_Block::LoadBlockShapes(const TopoDS_Shell& theShell, + const TopoDS_Vertex& theVertex000, + const TopoDS_Vertex& theVertex001, +// TopTools_IndexedMapOfShape& theShapeIDMap + TopTools_IndexedMapOfOrientedShape& theShapeIDMap ) +{ + MESSAGE(" ::LoadBlockShapes()"); + + myShell = theShell; + myNbIterations = 0; + mySumDist = 0; + myGridComputed = false; + + // 6 vertices + TopoDS_Shape V000, V100, V010, V110, V001, V101, V011, V111; + // 12 edges + TopoDS_Shape Ex00, Ex10, Ex01, Ex11; + TopoDS_Shape E0y0, E1y0, E0y1, E1y1; + TopoDS_Shape E00z, E10z, E01z, E11z; + // 6 faces + TopoDS_Shape Fxy0, Fx0z, F0yz, Fxy1, Fx1z, F1yz; + + // nb of faces bound to a vertex in TopTools_IndexedDataMapOfShapeListOfShape + // filled by TopExp::MapShapesAndAncestors() + const int NB_FACES_BY_VERTEX = 6; + + TopTools_IndexedDataMapOfShapeListOfShape vfMap; + TopExp::MapShapesAndAncestors( myShell, TopAbs_VERTEX, TopAbs_FACE, vfMap ); + if ( vfMap.Extent() != 8 ) { + MESSAGE(" Wrong nb of vertices in the block: " << vfMap.Extent() ); + return false; + } + + V000 = theVertex000; + V001 = theVertex001; + + if ( V000.IsNull() ) { + // find vertex 000 - the one with smallest coordinates + double minVal = DBL_MAX, minX, val; + for ( int i = 1; i <= 8; i++ ) { + const TopoDS_Vertex& v = TopoDS::Vertex( vfMap.FindKey( i )); + gp_Pnt P = BRep_Tool::Pnt( v ); + val = P.X() + P.Y() + P.Z(); + if ( val < minVal || ( val == minVal && P.X() < minX )) { + V000 = v; + minVal = val; + minX = P.X(); + } + } + // find vertex 001 - the one on the most vertical edge passing through V000 + TopTools_IndexedDataMapOfShapeListOfShape veMap; + TopExp::MapShapesAndAncestors( myShell, TopAbs_VERTEX, TopAbs_EDGE, veMap ); + gp_Vec dir001 = gp::DZ(); + gp_Pnt p000 = BRep_Tool::Pnt( TopoDS::Vertex( V000 )); + double maxVal = -DBL_MAX; + TopTools_ListIteratorOfListOfShape eIt ( veMap.FindFromKey( V000 )); + for ( ; eIt.More(); eIt.Next() ) { + const TopoDS_Edge& e = TopoDS::Edge( eIt.Value() ); + TopoDS_Vertex v = TopExp::FirstVertex( e ); + if ( v.IsSame( V000 )) + v = TopExp::LastVertex( e ); + val = dir001 * gp_Vec( p000, BRep_Tool::Pnt( v )).Normalized(); + if ( val > maxVal ) { + V001 = v; + maxVal = val; + } + } + } + + // find the bottom (Fxy0), Fx0z and F0yz faces + + const TopTools_ListOfShape& f000List = vfMap.FindFromKey( V000 ); + const TopTools_ListOfShape& f001List = vfMap.FindFromKey( V001 ); + if (f000List.Extent() != NB_FACES_BY_VERTEX || + f001List.Extent() != NB_FACES_BY_VERTEX ) { + MESSAGE(" LoadBlockShapes() " << f000List.Extent() << " " << f001List.Extent()); + return false; + } + TopTools_ListIteratorOfListOfShape f001It, f000It ( f000List ); + int i, j, iFound1, iFound2; + for ( j = 0; f000It.More(); f000It.Next(), j++ ) + { + if ( NB_FACES_BY_VERTEX == 6 && j % 2 ) continue; // each face encounters twice + const TopoDS_Shape& F = f000It.Value(); + for ( i = 0, f001It.Initialize( f001List ); f001It.More(); f001It.Next(), i++ ) { + if ( NB_FACES_BY_VERTEX == 6 && i % 2 ) continue; // each face encounters twice + if ( F.IsSame( f001It.Value() )) + break; + } + if ( f001It.More() ) // Fx0z or F0yz found + if ( Fx0z.IsNull() ) { + Fx0z = F; + iFound1 = i; + } else { + F0yz = F; + iFound2 = i; + } + else // F is the bottom face + Fxy0 = F; + } + if ( Fxy0.IsNull() || Fx0z.IsNull() || F0yz.IsNull() ) { + MESSAGE( Fxy0.IsNull() <<" "<< Fx0z.IsNull() <<" "<< F0yz.IsNull() ); + return false; + } + + // choose the top face (Fxy1) + for ( i = 0, f001It.Initialize( f001List ); f001It.More(); f001It.Next(), i++ ) { + if ( NB_FACES_BY_VERTEX == 6 && i % 2 ) continue; // each face encounters twice + if ( i != iFound1 && i != iFound2 ) + break; + } + Fxy1 = f001It.Value(); + if ( Fxy1.IsNull() ) { + MESSAGE(" LoadBlockShapes() error "); + return false; + } + + // find bottom edges and veritices + list< TopoDS_Edge > eList; + list< int > nbVertexInWires; + getOrderedEdges( TopoDS::Face( Fxy0 ), TopoDS::Vertex( V000 ), eList, nbVertexInWires ); + if ( nbVertexInWires.size() != 1 || nbVertexInWires.front() != 4 ) { + MESSAGE(" LoadBlockShapes() error "); + return false; + } + list< TopoDS_Edge >::iterator elIt = eList.begin(); + for ( i = 0; elIt != eList.end(); elIt++, i++ ) + switch ( i ) { + case 0: E0y0 = *elIt; V010 = TopExp::LastVertex( *elIt, true ); break; + case 1: Ex10 = *elIt; V110 = TopExp::LastVertex( *elIt, true ); break; + case 2: E1y0 = *elIt; V100 = TopExp::LastVertex( *elIt, true ); break; + case 3: Ex00 = *elIt; break; + default:; + } + if ( i != 4 || E0y0.IsNull() || Ex10.IsNull() || E1y0.IsNull() || Ex00.IsNull() ) { + MESSAGE(" LoadBlockShapes() error, eList.size()=" << eList.size()); + return false; + } + + + // find top edges and veritices + eList.clear(); + getOrderedEdges( TopoDS::Face( Fxy1 ), TopoDS::Vertex( V001 ), eList, nbVertexInWires ); + if ( nbVertexInWires.size() != 1 || nbVertexInWires.front() != 4 ) { + MESSAGE(" LoadBlockShapes() error "); + return false; + } + for ( i = 0, elIt = eList.begin(); elIt != eList.end(); elIt++, i++ ) + switch ( i ) { + case 0: Ex01 = *elIt; V101 = TopExp::LastVertex( *elIt, true ); break; + case 1: E1y1 = *elIt; V111 = TopExp::LastVertex( *elIt, true ); break; + case 2: Ex11 = *elIt; V011 = TopExp::LastVertex( *elIt, true ); break; + case 3: E0y1 = *elIt; break; + default:; + } + if ( i != 4 || Ex01.IsNull() || E1y1.IsNull() || Ex11.IsNull() || E0y1.IsNull() ) { + MESSAGE(" LoadBlockShapes() error, eList.size()=" << eList.size()); + return false; + } + + // swap Fx0z and F0yz if necessary + TopExp_Explorer exp( Fx0z, TopAbs_VERTEX ); + for ( ; exp.More(); exp.Next() ) // Fx0z shares V101 and V100 + if ( V101.IsSame( exp.Current() ) || V100.IsSame( exp.Current() )) + break; // V101 or V100 found + if ( !exp.More() ) { // not found + TopoDS_Shape f = Fx0z; Fx0z = F0yz; F0yz = f; + } + + // find Fx1z and F1yz faces + const TopTools_ListOfShape& f111List = vfMap.FindFromKey( V111 ); + const TopTools_ListOfShape& f110List = vfMap.FindFromKey( V110 ); + if (f111List.Extent() != NB_FACES_BY_VERTEX || + f110List.Extent() != NB_FACES_BY_VERTEX ) { + MESSAGE(" LoadBlockShapes() " << f111List.Extent() << " " << f110List.Extent()); + return false; + } + TopTools_ListIteratorOfListOfShape f111It, f110It ( f110List); + for ( j = 0 ; f110It.More(); f110It.Next(), j++ ) { + if ( NB_FACES_BY_VERTEX == 6 && j % 2 ) continue; // each face encounters twice + const TopoDS_Shape& F = f110It.Value(); + for ( i = 0, f111It.Initialize( f111List ); f111It.More(); f111It.Next(), i++ ) { + if ( NB_FACES_BY_VERTEX == 6 && i % 2 ) continue; // each face encounters twice + if ( F.IsSame( f111It.Value() )) { // Fx1z or F1yz found + if ( Fx1z.IsNull() ) + Fx1z = F; + else + F1yz = F; + } + } + } + if ( Fx1z.IsNull() || F1yz.IsNull() ) { + MESSAGE(" LoadBlockShapes() error "); + return false; + } + + // swap Fx1z and F1yz if necessary + for ( exp.Init( Fx1z, TopAbs_VERTEX ); exp.More(); exp.Next() ) + if ( V010.IsSame( exp.Current() ) || V011.IsSame( exp.Current() )) + break; + if ( !exp.More() ) { + TopoDS_Shape f = Fx1z; Fx1z = F1yz; F1yz = f; + } + + // find vertical edges + for ( exp.Init( Fx0z, TopAbs_EDGE ); exp.More(); exp.Next() ) { + const TopoDS_Edge& edge = TopoDS::Edge( exp.Current() ); + const TopoDS_Shape& vFirst = TopExp::FirstVertex( edge, true ); + if ( vFirst.IsSame( V001 )) + E00z = edge; + else if ( vFirst.IsSame( V100 )) + E10z = edge; + } + if ( E00z.IsNull() || E10z.IsNull() ) { + MESSAGE(" LoadBlockShapes() error "); + return false; + } + for ( exp.Init( Fx1z, TopAbs_EDGE ); exp.More(); exp.Next() ) { + const TopoDS_Edge& edge = TopoDS::Edge( exp.Current() ); + const TopoDS_Shape& vFirst = TopExp::FirstVertex( edge, true ); + if ( vFirst.IsSame( V111 )) + E11z = edge; + else if ( vFirst.IsSame( V010 )) + E01z = edge; + } + if ( E01z.IsNull() || E11z.IsNull() ) { + MESSAGE(" LoadBlockShapes() error "); + return false; + } + + // load shapes in theShapeIDMap + + theShapeIDMap.Clear(); + + theShapeIDMap.Add(V000.Oriented( TopAbs_FORWARD )); + theShapeIDMap.Add(V100.Oriented( TopAbs_FORWARD )); + theShapeIDMap.Add(V010.Oriented( TopAbs_FORWARD )); + theShapeIDMap.Add(V110.Oriented( TopAbs_FORWARD )); + theShapeIDMap.Add(V001.Oriented( TopAbs_FORWARD )); + theShapeIDMap.Add(V101.Oriented( TopAbs_FORWARD )); + theShapeIDMap.Add(V011.Oriented( TopAbs_FORWARD )); + theShapeIDMap.Add(V111.Oriented( TopAbs_FORWARD )); + + theShapeIDMap.Add(Ex00); + theShapeIDMap.Add(Ex10); + theShapeIDMap.Add(Ex01); + theShapeIDMap.Add(Ex11); + + theShapeIDMap.Add(E0y0); + theShapeIDMap.Add(E1y0); + theShapeIDMap.Add(E0y1); + theShapeIDMap.Add(E1y1); + + theShapeIDMap.Add(E00z); + theShapeIDMap.Add(E10z); + theShapeIDMap.Add(E01z); + theShapeIDMap.Add(E11z); + + theShapeIDMap.Add(Fxy0); + theShapeIDMap.Add(Fxy1); + theShapeIDMap.Add(Fx0z); + theShapeIDMap.Add(Fx1z); + theShapeIDMap.Add(F0yz); + theShapeIDMap.Add(F1yz); + + theShapeIDMap.Add(myShell); + + if ( theShapeIDMap.Extent() != 27 ) { + MESSAGE("LoadBlockShapes() " << theShapeIDMap.Extent() ); + return false; + } + + // store shapes geometry + for ( int shapeID = 1; shapeID < theShapeIDMap.Extent(); shapeID++ ) + { + const TopoDS_Shape& S = theShapeIDMap( shapeID ); + switch ( S.ShapeType() ) + { + case TopAbs_VERTEX: { + + if ( shapeID > ID_V111 ) { + MESSAGE(" shapeID =" << shapeID ); + return false; + } + myPnt[ shapeID - ID_V000 ] = + BRep_Tool::Pnt( TopoDS::Vertex( S )).XYZ(); + break; + } + case TopAbs_EDGE: { + + const TopoDS_Edge& edge = TopoDS::Edge( S ); + if ( shapeID < ID_Ex00 || shapeID > ID_E11z || edge.IsNull() ) { + MESSAGE(" shapeID =" << shapeID ); + return false; + } + TEdge& tEdge = myEdge[ shapeID - ID_Ex00 ]; + tEdge.myCoordInd = GetCoordIndOnEdge( shapeID ); + TopLoc_Location loc; + tEdge.myC3d = BRep_Tool::Curve( edge, loc, tEdge.myFirst, tEdge.myLast ); + if ( !IsForwardEdge( edge, theShapeIDMap )) + Swap( tEdge.myFirst, tEdge.myLast ); + tEdge.myTrsf = loc; + break; + } + case TopAbs_FACE: { + + const TopoDS_Face& face = TopoDS::Face( S ); + if ( shapeID < ID_Fxy0 || shapeID > ID_F1yz || face.IsNull() ) { + MESSAGE(" shapeID =" << shapeID ); + return false; + } + TFace& tFace = myFace[ shapeID - ID_Fxy0 ]; + // pcurves + vector< int > edgeIdVec(4, -1); + GetFaceEdgesIDs( shapeID, edgeIdVec ); + for ( int iE = 0; iE < 4; iE++ ) // loop on 4 edges + { + const TopoDS_Edge& edge = TopoDS::Edge( theShapeIDMap( edgeIdVec[ iE ])); + tFace.myCoordInd[ iE ] = GetCoordIndOnEdge( edgeIdVec[ iE ] ); + tFace.myC2d[ iE ] = + BRep_Tool::CurveOnSurface( edge, face, tFace.myFirst[iE], tFace.myLast[iE] ); + if ( !IsForwardEdge( edge, theShapeIDMap )) + Swap( tFace.myFirst[ iE ], tFace.myLast[ iE ] ); + } + // 2d corners + tFace.myCorner[ 0 ] = tFace.myC2d[ 0 ]->Value( tFace.myFirst[0] ).XY(); + tFace.myCorner[ 1 ] = tFace.myC2d[ 0 ]->Value( tFace.myLast[0] ).XY(); + tFace.myCorner[ 2 ] = tFace.myC2d[ 1 ]->Value( tFace.myLast[1] ).XY(); + tFace.myCorner[ 3 ] = tFace.myC2d[ 1 ]->Value( tFace.myFirst[1] ).XY(); + // sufrace + TopLoc_Location loc; + tFace.myS = BRep_Tool::Surface( face, loc ); + tFace.myTrsf = loc; + break; + } + default: break; + } + } // loop on shapes in theShapeIDMap + + return true; +} + +//======================================================================= +//function : GetFaceEdgesIDs +//purpose : return edges IDs in the order u0, u1, 0v, 1v +// u0 means "|| u, v == 0" +//======================================================================= + +void SMESH_Block::GetFaceEdgesIDs (const int faceID, vector< int >& edgeVec ) +{ + switch ( faceID ) { + case ID_Fxy0: + edgeVec[ 0 ] = ID_Ex00; + edgeVec[ 1 ] = ID_Ex10; + edgeVec[ 2 ] = ID_E0y0; + edgeVec[ 3 ] = ID_E1y0; + break; + case ID_Fxy1: + edgeVec[ 0 ] = ID_Ex01; + edgeVec[ 1 ] = ID_Ex11; + edgeVec[ 2 ] = ID_E0y1; + edgeVec[ 3 ] = ID_E1y1; + break; + case ID_Fx0z: + edgeVec[ 0 ] = ID_Ex00; + edgeVec[ 1 ] = ID_Ex01; + edgeVec[ 2 ] = ID_E00z; + edgeVec[ 3 ] = ID_E10z; + break; + case ID_Fx1z: + edgeVec[ 0 ] = ID_Ex10; + edgeVec[ 1 ] = ID_Ex11; + edgeVec[ 2 ] = ID_E01z; + edgeVec[ 3 ] = ID_E11z; + break; + case ID_F0yz: + edgeVec[ 0 ] = ID_E0y0; + edgeVec[ 1 ] = ID_E0y1; + edgeVec[ 2 ] = ID_E00z; + edgeVec[ 3 ] = ID_E01z; + break; + case ID_F1yz: + edgeVec[ 0 ] = ID_E1y0; + edgeVec[ 1 ] = ID_E1y1; + edgeVec[ 2 ] = ID_E10z; + edgeVec[ 3 ] = ID_E11z; + break; + default: + MESSAGE(" GetFaceEdgesIDs(), wrong face ID: " << faceID ); + } +} diff --git a/src/SMESH/SMESH_Block.hxx b/src/SMESH/SMESH_Block.hxx new file mode 100644 index 000000000..d937aeddd --- /dev/null +++ b/src/SMESH/SMESH_Block.hxx @@ -0,0 +1,209 @@ +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org + +// File : SMESH_Block.hxx +// Created : Tue Nov 30 12:42:18 2004 +// Author : Edward AGAPOV (eap) + + +#ifndef SMESH_Block_HeaderFile +#define SMESH_Block_HeaderFile + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +// ========================================================= +// class calculating coordinates of 3D points by normalized +// parameters inside the block and vice versa +// ========================================================= + +class SMESH_Block: public math_FunctionSetWithDerivatives +{ + public: + enum TShapeID { // ids of the block sub-shapes + ID_NONE = 0, + + ID_V000 = 1, ID_V100, ID_V010, ID_V110, ID_V001, ID_V101, ID_V011, ID_V111, + + ID_Ex00, ID_Ex10, ID_Ex01, ID_Ex11, + ID_E0y0, ID_E1y0, ID_E0y1, ID_E1y1, + ID_E00z, ID_E10z, ID_E01z, ID_E11z, + + ID_Fxy0, ID_Fxy1, ID_Fx0z, ID_Fx1z, ID_F0yz, ID_F1yz, + + ID_Shell + }; + static inline bool IsVertexID( int theShapeID ) + { return ( theShapeID >= ID_V000 && theShapeID <= ID_V111 ); } + + static inline bool IsEdgeID( int theShapeID ) + { return ( theShapeID >= ID_Ex00 && theShapeID <= ID_E11z ); } + + static inline bool IsFaceID( int theShapeID ) + { return ( theShapeID >= ID_Fxy0 && theShapeID <= ID_F1yz ); } + + + SMESH_Block (): myNbIterations(0), mySumDist(0.) {} + + bool LoadBlockShapes(const TopoDS_Shell& theShell, + const TopoDS_Vertex& theVertex000, + const TopoDS_Vertex& theVertex001, +// TopTools_IndexedMapOfShape& theShapeIDMap + TopTools_IndexedMapOfOrientedShape& theShapeIDMap ); + // add sub-shapes of theBlock to theShapeIDMap so that they get + // IDs acoording to enum TShapeID + + static int GetShapeIDByParams ( const gp_XYZ& theParams ); + // define an id of the block sub-shape by point parameters + + bool VertexPoint( const int theVertexID, gp_XYZ& thePoint ) const { + if ( !IsVertexID( theVertexID )) return false; + thePoint = myPnt[ theVertexID - ID_V000 ]; return true; + } + // return vertex coordinates + + bool EdgePoint( const int theEdgeID, const gp_XYZ& theParams, gp_XYZ& thePoint ) const { + if ( !IsEdgeID( theEdgeID )) return false; + thePoint = myEdge[ theEdgeID - ID_Ex00 ].Point( theParams ); return true; + } + // return coordinates of a point on edge + + bool FacePoint( const int theFaceID, const gp_XYZ& theParams, gp_XYZ& thePoint ) const { + if ( !IsFaceID ( theFaceID )) return false; + thePoint = myFace[ theFaceID - ID_Fxy0 ].Point( theParams ); return true; + } + // return coordinates of a point on face + + bool ShellPoint( const gp_XYZ& theParams, gp_XYZ& thePoint ) const; + // return coordinates of a point in shell + + bool ComputeParameters (const gp_Pnt& thePoint, + gp_XYZ& theParams, + const int theShapeID = ID_Shell); + // compute point parameters in the block + + static void GetFaceEdgesIDs (const int faceID, vector< int >& edgeVec ); + // return edges IDs of a face in the order u0, u1, 0v, 1v + + static int GetCoordIndOnEdge (const int theEdgeID) + { return (theEdgeID < ID_E0y0) ? 1 : (theEdgeID < ID_E00z) ? 2 : 3; } + // return an index of a coordinate which varies along the edge + + static double* GetShapeCoef (const int theShapeID); + // for theShapeID( TShapeID ), returns 3 coefficients used + // to compute an addition of an on-theShape point to coordinates + // of an in-shell point. If an in-shell point has parameters (Px,Py,Pz), + // then the addition of a point P is computed as P*kx*ky*kz and ki is + // defined by the returned coef like this: + // ki = (coef[i] == 0) ? 1 : (coef[i] < 0) ? 1 - Pi : Pi + + static bool IsForwardEdge (const TopoDS_Edge & theEdge, + //TopTools_IndexedMapOfShape& theShapeIDMap + TopTools_IndexedMapOfOrientedShape& theShapeIDMap) { + int v1ID = theShapeIDMap.FindIndex( TopExp::FirstVertex( theEdge ).Oriented( TopAbs_FORWARD )); + int v2ID = theShapeIDMap.FindIndex( TopExp::LastVertex( theEdge ).Oriented( TopAbs_FORWARD )); + return ( v1ID < v2ID ); + } + // Return true if an in-block parameter increases along theEdge curve + + static void Swap(double& a, double& b) { double tmp = a; a = b; b = tmp; } + + // methods of math_FunctionSetWithDerivatives + Standard_Integer NbVariables() const; + Standard_Integer NbEquations() const; + Standard_Boolean Value(const math_Vector& X,math_Vector& F) ; + Standard_Boolean Derivatives(const math_Vector& X,math_Matrix& D) ; + Standard_Boolean Values(const math_Vector& X,math_Vector& F,math_Matrix& D) ; + Standard_Integer GetStateNumber (); + + static ostream& DumpShapeID (const int theBlockShapeID, ostream& stream); + // DEBUG: dump an id of a block sub-shape + + private: + + struct TEdge { + int myCoordInd; + double myFirst; + double myLast; + Handle(Geom_Curve) myC3d; + gp_Trsf myTrsf; + double GetU( const gp_XYZ& theParams ) const; + gp_XYZ Point( const gp_XYZ& theParams ) const; + }; + + struct TFace { + // 4 edges in the order u0, u1, 0v, 1v + int myCoordInd[ 4 ]; + double myFirst [ 4 ]; + double myLast [ 4 ]; + Handle(Geom2d_Curve) myC2d [ 4 ]; + // 4 corner points in the order 00, 10, 11, 01 + gp_XY myCorner [ 4 ]; + // surface + Handle(Geom_Surface) myS; + gp_Trsf myTrsf; + gp_XY GetUV( const gp_XYZ& theParams ) const; + gp_XYZ Point( const gp_XYZ& theParams ) const; + int GetUInd() const { return myCoordInd[ 0 ]; } + int GetVInd() const { return myCoordInd[ 2 ]; } + }; + + TopoDS_Shell myShell; + // geometry: + // 8 vertices + gp_XYZ myPnt[ 8 ]; + // 12 edges + TEdge myEdge[ 12 ]; + // 6 faces + TFace myFace[ 6 ]; + + // for param computation + + int myFaceIndex; + double myFaceParam; + int myNbIterations; + double mySumDist; + + gp_XYZ myPoint; // the given point + gp_XYZ myParam; // the best parameters guess + double myValues[ 4 ]; // values computed at myParam + + typedef pair TxyzPair; + TxyzPair my3x3x3GridNodes[ 27 ]; + bool myGridComputed; +}; + + +#endif diff --git a/src/SMESH/SMESH_Gen.cxx b/src/SMESH/SMESH_Gen.cxx index 3a202a347..01d864c6f 100644 --- a/src/SMESH/SMESH_Gen.cxx +++ b/src/SMESH/SMESH_Gen.cxx @@ -208,12 +208,21 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) // mesh the rest subshapes starting from vertices // ----------------------------------------------- - smToCompute = sm->GetFirstToCompute(); - while (smToCompute) + int i, nbSub = smMap.size(); + map::const_iterator itSub = smMap.begin(); + for ( i = 0; i <= nbSub; ++i ) // loop on the whole map plus { + if ( itSub == smMap.end() ) + smToCompute = sm; + else + smToCompute = (itSub++)->second; + if (smToCompute->GetComputeState() != SMESH_subMesh::READY_TO_COMPUTE) { + if (smToCompute->GetComputeState() == SMESH_subMesh::FAILED_TO_COMPUTE) + ret = false; + continue; + } TopoDS_Shape subShape = smToCompute->GetSubShape(); - int dim = GetShapeDim(subShape); - if (dim > 0) + if ( subShape.ShapeType() != TopAbs_VERTEX ) { if ( !smToCompute->ComputeStateEngine(SMESH_subMesh::COMPUTE) ) ret = false; @@ -229,22 +238,10 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) smToCompute->ComputeStateEngine(SMESH_subMesh::COMPUTE); } } - smToCompute = sm->GetFirstToCompute(); } - if (!ret) return false; - - // JFA for PAL6524: if there are failed sub-meshes, return Standard_False - const map < int, SMESH_subMesh * >&subMeshes = sm->DependsOn(); - map < int, SMESH_subMesh * >::const_iterator itsub; - for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++) { - SMESH_subMesh *smi = (*itsub).second; - if (smi->GetComputeState() == SMESH_subMesh::FAILED_TO_COMPUTE) return false; - } - if (sm->GetComputeState() == SMESH_subMesh::FAILED_TO_COMPUTE) return false; - - MESSAGE( "VSR - SMESH_Gen::Compute() finished" ); - return true; + MESSAGE( "VSR - SMESH_Gen::Compute() finished, OK = " << ret); + return ret; } diff --git a/src/SMESH/SMESH_Hypothesis.cxx b/src/SMESH/SMESH_Hypothesis.cxx index dac1ee325..0107c3e36 100644 --- a/src/SMESH/SMESH_Hypothesis.cxx +++ b/src/SMESH/SMESH_Hypothesis.cxx @@ -30,6 +30,7 @@ using namespace std; using namespace std; #include "SMESH_Hypothesis.hxx" #include "SMESH_Gen.hxx" +#include "SMESH_subMesh.hxx" #include "utilities.h" //============================================================================= diff --git a/src/SMESH/SMESH_Mesh.cxx b/src/SMESH/SMESH_Mesh.cxx index 50c793296..0c05113cf 100644 --- a/src/SMESH/SMESH_Mesh.cxx +++ b/src/SMESH/SMESH_Mesh.cxx @@ -46,11 +46,18 @@ #include "DriverUNV_R_SMDS_Mesh.h" #include "DriverSTL_R_SMDS_Mesh.h" +#include +#include +#include + #include -#include -#include #include +#include +#include #include + +#include + #include "Utils_ExceptHandlers.hxx" #ifdef _DEBUG_ @@ -254,8 +261,7 @@ SMESH_Hypothesis::Hypothesis_Status } SMESH_Hypothesis *anHyp = sc->mapHypothesis[anHypId]; - if(MYDEBUG) SCRUTE( anHyp->GetName() ); - int event; + MESSAGE( "SMESH_Mesh::AddHypothesis " << anHyp->GetName() ); bool isGlobalHyp = IsMainShape( aSubShape ); @@ -272,6 +278,7 @@ SMESH_Hypothesis::Hypothesis_Status // shape + int event; if (anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO) event = SMESH_subMesh::ADD_HYP; else @@ -290,10 +297,26 @@ SMESH_Hypothesis::Hypothesis_Status subMesh->SubMeshesAlgoStateEngine(event, anHyp); if (ret2 > ret) ret = ret2; + + // check concurent hypotheses on ansestors + if (ret < SMESH_Hypothesis::HYP_CONCURENT && !isGlobalHyp ) + { + const map < int, SMESH_subMesh * >& smMap = subMesh->DependsOn(); + map < int, SMESH_subMesh * >::const_iterator smIt = smMap.begin(); + for ( ; smIt != smMap.end(); smIt++ ) { + if ( smIt->second->IsApplicableHypotesis( anHyp )) { + ret2 = smIt->second->CheckConcurentHypothesis( anHyp->GetType() ); + if (ret2 > ret) { + ret = ret2; + break; + } + } + } + } } - subMesh->DumpAlgoState(true); - if(MYDEBUG) SCRUTE(ret); + if(MYDEBUG) subMesh->DumpAlgoState(true); + SCRUTE(ret); return ret; } @@ -347,22 +370,44 @@ SMESH_Hypothesis::Hypothesis_Status else event = SMESH_subMesh::REMOVE_ALGO; SMESH_Hypothesis::Hypothesis_Status ret = subMesh->AlgoStateEngine(event, anHyp); - + + // there may appear concurrent hyps that were covered by the removed hyp + if (ret < SMESH_Hypothesis::HYP_CONCURENT && + subMesh->IsApplicableHypotesis( anHyp ) && + subMesh->CheckConcurentHypothesis( anHyp->GetType() ) != SMESH_Hypothesis::HYP_OK) + ret = SMESH_Hypothesis::HYP_CONCURENT; + // subShapes if (!SMESH_Hypothesis::IsStatusFatal(ret) && !subMesh->IsApplicableHypotesis( anHyp )) // is removed from father + { + if (anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO) + event = SMESH_subMesh::REMOVE_FATHER_HYP; + else + event = SMESH_subMesh::REMOVE_FATHER_ALGO; + SMESH_Hypothesis::Hypothesis_Status ret2 = + subMesh->SubMeshesAlgoStateEngine(event, anHyp); + if (ret2 > ret) // more severe + ret = ret2; + + // check concurent hypotheses on ansestors + if (ret < SMESH_Hypothesis::HYP_CONCURENT && !IsMainShape( aSubShape ) ) { - if (anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO) - event = SMESH_subMesh::REMOVE_FATHER_HYP; - else - event = SMESH_subMesh::REMOVE_FATHER_ALGO; - SMESH_Hypothesis::Hypothesis_Status ret2 = - subMesh->SubMeshesAlgoStateEngine(event, anHyp); - if (ret2 > ret) // more severe - ret = ret2; + const map < int, SMESH_subMesh * >& smMap = subMesh->DependsOn(); + map < int, SMESH_subMesh * >::const_iterator smIt = smMap.begin(); + for ( ; smIt != smMap.end(); smIt++ ) { + if ( smIt->second->IsApplicableHypotesis( anHyp )) { + ret2 = smIt->second->CheckConcurentHypothesis( anHyp->GetType() ); + if (ret2 > ret) { + ret = ret2; + break; + } + } + } } + } - subMesh->DumpAlgoState(true); + if(MYDEBUG) subMesh->DumpAlgoState(true); if(MYDEBUG) SCRUTE(ret); return ret; } @@ -864,6 +909,256 @@ void SMESH_Mesh::RemoveGroup (const int theGroupID) delete _mapGroup[theGroupID]; } +//============================================================================= +/*! + * IsLocal1DHypothesis + * Check, if there is 1D hypothesis assigned directly on + */ +//============================================================================= +bool SMESH_Mesh::IsLocal1DHypothesis (const TopoDS_Shape& theEdge) +{ + const SMESHDS_Mesh* meshDS = GetMeshDS(); + const list& listHyp = meshDS->GetHypothesis(theEdge); + list::const_iterator it = listHyp.begin(); + + for (; it != listHyp.end(); it++) { + const SMESH_Hypothesis * aHyp = static_cast(*it); + if (aHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO && + aHyp->GetDim() == 1) { // 1D Hypothesis found + return true; + } + } + return false; +} + +//============================================================================= +/*! + * IsPropagationHypothesis + */ +//============================================================================= +bool SMESH_Mesh::IsPropagationHypothesis (const TopoDS_Shape& theEdge) +{ + return _mapPropagationChains.Contains(theEdge); +} + +//============================================================================= +/*! + * IsPropagatedHypothesis + */ +//============================================================================= +bool SMESH_Mesh::IsPropagatedHypothesis (const TopoDS_Shape& theEdge, + TopoDS_Shape& theMainEdge) +{ + int nbChains = _mapPropagationChains.Extent(); + for (int i = 1; i <= nbChains; i++) { + const TopTools_IndexedMapOfShape& aChain = _mapPropagationChains.FindFromIndex(i); + if (aChain.Contains(theEdge)) { + theMainEdge = _mapPropagationChains.FindKey(i); + return true; + } + } + + return false; +} + +//============================================================================= +/*! + * CleanMeshOnPropagationChain + */ +//============================================================================= +void SMESH_Mesh::CleanMeshOnPropagationChain (const TopoDS_Shape& theMainEdge) +{ + const TopTools_IndexedMapOfShape& aChain = _mapPropagationChains.FindFromKey(theMainEdge); + int i, nbEdges = aChain.Extent(); + for (i = 1; i <= nbEdges; i++) { + TopoDS_Shape anEdge = aChain.FindKey(i); + SMESH_subMesh *subMesh = GetSubMesh(anEdge); + SMESHDS_SubMesh *subMeshDS = subMesh->GetSubMeshDS(); + if (subMeshDS && subMeshDS->NbElements() > 0) { + subMesh->ComputeStateEngine(SMESH_subMesh::CLEANDEP); + } + } +} + +//============================================================================= +/*! + * RebuildPropagationChains + * Rebuild all existing propagation chains. + * Have to be used, if 1D hypothesis have been assigned/removed to/from any edge + */ +//============================================================================= +bool SMESH_Mesh::RebuildPropagationChains() +{ + bool ret = true; + + // Clean all chains, because they can be not up-to-date + int i, nbChains = _mapPropagationChains.Extent(); + for (i = 1; i <= nbChains; i++) { + TopoDS_Shape aMainEdge = _mapPropagationChains.FindKey(i); + CleanMeshOnPropagationChain(aMainEdge); + _mapPropagationChains.ChangeFromIndex(i).Clear(); + } + + // Build all chains + for (i = 1; i <= nbChains; i++) { + TopoDS_Shape aMainEdge = _mapPropagationChains.FindKey(i); + if (!BuildPropagationChain(aMainEdge)) + ret = false; + CleanMeshOnPropagationChain(aMainEdge); + } + + return ret; +} + +//============================================================================= +/*! + * RemovePropagationChain + * Have to be used, if Propagation hypothesis is removed from + */ +//============================================================================= +bool SMESH_Mesh::RemovePropagationChain (const TopoDS_Shape& theMainEdge) +{ + if (!_mapPropagationChains.Contains(theMainEdge)) + return false; + + // Clean mesh elements and nodes, built on the chain + CleanMeshOnPropagationChain(theMainEdge); + + // Clean the chain + _mapPropagationChains.ChangeFromKey(theMainEdge).Clear(); + + // Remove the chain from the map + int i = _mapPropagationChains.FindIndex(theMainEdge); + TopoDS_Vertex anEmptyShape; + BRep_Builder BB; + BB.MakeVertex(anEmptyShape, gp_Pnt(0,0,0), 0.1); + TopTools_IndexedMapOfShape anEmptyMap; + _mapPropagationChains.Substitute(i, anEmptyShape, anEmptyMap); + + return true; +} + +//============================================================================= +/*! + * BuildPropagationChain + */ +//============================================================================= +bool SMESH_Mesh::BuildPropagationChain (const TopoDS_Shape& theMainEdge) +{ + if (theMainEdge.ShapeType() != TopAbs_EDGE) return true; + + // Add new chain, if there is no + if (!_mapPropagationChains.Contains(theMainEdge)) { + TopTools_IndexedMapOfShape aNewChain; + _mapPropagationChains.Add(theMainEdge, aNewChain); + } + + // Check presence of 1D hypothesis to be propagated + if (!IsLocal1DHypothesis(theMainEdge)) { + MESSAGE("Warning: There is no 1D hypothesis to propagate. Please, assign."); + return true; + } + + // Edges, on which the 1D hypothesis will be propagated from + TopTools_IndexedMapOfShape& aChain = _mapPropagationChains.ChangeFromKey(theMainEdge); + if (aChain.Extent() > 0) { + CleanMeshOnPropagationChain(theMainEdge); + aChain.Clear(); + } + + // At first put in the chain + aChain.Add(theMainEdge); + + // List of edges, added to chain on the previous cycle pass + TopTools_ListOfShape listPrevEdges; + listPrevEdges.Append(theMainEdge); + +// 5____4____3____4____5____6 +// | | | | | | +// | | | | | | +// 4____3____2____3____4____5 +// | | | | | | Number in the each knot of +// | | | | | | grid indicates cycle pass, +// 3____2____1____2____3____4 on which corresponding edge +// | | | | | | (perpendicular to the plane +// | | | | | | of view) will be found. +// 2____1____0____1____2____3 +// | | | | | | +// | | | | | | +// 3____2____1____2____3____4 + + // Collect all edges pass by pass + while (listPrevEdges.Extent() > 0) { + // List of edges, added to chain on this cycle pass + TopTools_ListOfShape listCurEdges; + + // Find the next portion of edges + TopTools_ListIteratorOfListOfShape itE (listPrevEdges); + for (; itE.More(); itE.Next()) { + TopoDS_Shape anE = itE.Value(); + + // Iterate on faces, having edge + TopTools_ListIteratorOfListOfShape itA (GetAncestors(anE)); + for (; itA.More(); itA.Next()) { + TopoDS_Shape aW = itA.Value(); + + // There are objects of different type among the ancestors of edge + if (aW.ShapeType() == TopAbs_WIRE) { + TopoDS_Shape anOppE; + + BRepTools_WireExplorer aWE (TopoDS::Wire(aW)); + Standard_Integer nb = 1, found = 0; + TopTools_Array1OfShape anEdges (1,4); + for (; aWE.More(); aWE.Next(), nb++) { + if (nb > 4) { + found = 0; + break; + } + anEdges(nb) = aWE.Current(); + if (!_mapAncestors.Contains(anEdges(nb))) { + MESSAGE("WIRE EXPLORER HAVE GIVEN AN INVALID EDGE !!!"); + break; + } else { + int ind = _mapAncestors.FindIndex(anEdges(nb)); + anEdges(nb) = _mapAncestors.FindKey(ind); + } + if (anEdges(nb).IsSame(anE)) found = nb; + } + + if (nb == 5 && found > 0) { + // Quadrangle face found, get an opposite edge + Standard_Integer opp = found + 2; + if (opp > 4) opp -= 4; + anOppE = anEdges(opp); + + if (!aChain.Contains(anOppE)) { + if (!IsLocal1DHypothesis(anOppE)) { + TopoDS_Shape aMainEdgeForOppEdge; + if (IsPropagatedHypothesis(anOppE, aMainEdgeForOppEdge)) { + // Collision! + MESSAGE("Error: Collision between propagated hypotheses"); + CleanMeshOnPropagationChain(theMainEdge); + aChain.Clear(); + return false; + } else { + // Add found edge to the chain + aChain.Add(anOppE); + listCurEdges.Append(anOppE); + } + } + } + } // if (nb == 5 && found > 0) + } // if (aF.ShapeType() == TopAbs_WIRE) + } // for (; itF.More(); itF.Next()) + } // for (; itE.More(); itE.Next()) + + listPrevEdges = listCurEdges; + } // while (listPrevEdges.Extent() > 0) + + CleanMeshOnPropagationChain(theMainEdge); + return true; +} + //======================================================================= //function : GetAncestors //purpose : return list of ancestors of theSubShape in the order diff --git a/src/SMESH/SMESH_Mesh.hxx b/src/SMESH/SMESH_Mesh.hxx index d594b7115..51f085364 100644 --- a/src/SMESH/SMESH_Mesh.hxx +++ b/src/SMESH/SMESH_Mesh.hxx @@ -29,13 +29,18 @@ #ifndef _SMESH_MESH_HXX_ #define _SMESH_MESH_HXX_ +#include "SMESH_Hypothesis.hxx" +//#include "SMESH_subMesh.hxx" + #include "SMESHDS_Document.hxx" #include "SMESHDS_Mesh.hxx" #include "SMESHDS_Command.hxx" -#include "SMESH_Hypothesis.hxx" -#include "SMESH_subMesh.hxx" #include "SMDSAbs_ElementType.hxx" +#include "NMTTools_IndexedDataMapOfShapeIndexedMapOfShape.hxx" + +#include "Utils_SALOME_Exception.hxx" + #include #include #include @@ -62,6 +67,9 @@ class SMESH_Gen; class SMESH_Group; class TopTools_ListOfShape; +class SMESH_subMesh; + +typedef NMTTools_IndexedDataMapOfShapeIndexedMapOfShape IndexedMapOfChain; class SMESH_Mesh { @@ -167,9 +175,35 @@ public: list GetGroupIds(); void RemoveGroup (const int theGroupID); + + // Propagation hypothesis management + + bool IsLocal1DHypothesis (const TopoDS_Shape& theEdge); + // Returns true, if a local 1D hypothesis is set directly on + + bool IsPropagationHypothesis (const TopoDS_Shape& theEdge); + // Returns true, if a local Propagation hypothesis is set directly on + + bool IsPropagatedHypothesis (const TopoDS_Shape& theEdge, + TopoDS_Shape& theMainEdge); + // Returns true, if a local 1D hypothesis is + // propagated on from some other edge. + // Returns through the edge, from + // which the 1D hypothesis is propagated on + + bool RebuildPropagationChains(); + bool RemovePropagationChain (const TopoDS_Shape& theMainEdge); + bool BuildPropagationChain (const TopoDS_Shape& theMainEdge); + + // ostream& Dump(ostream & save); +private: + // Propagation hypothesis management + void CleanMeshOnPropagationChain(const TopoDS_Shape& theMainEdge); + // + private: int _id; // id given by creator (unique within the creator instance) int _studyId; @@ -186,6 +220,8 @@ private: SMESH_Gen *_gen; TopTools_IndexedDataMapOfShapeListOfShape _mapAncestors; + + IndexedMapOfChain _mapPropagationChains; // Propagation hypothesis management }; #endif diff --git a/src/SMESH/SMESH_Pattern.cxx b/src/SMESH/SMESH_Pattern.cxx index 7f20a5cad..06595678e 100644 --- a/src/SMESH/SMESH_Pattern.cxx +++ b/src/SMESH/SMESH_Pattern.cxx @@ -1,8 +1,25 @@ -// File : SMESH_Pattern.cxx -// Created : Thu Aug 5 11:09:29 2004 +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org + +// File : SMESH_Pattern.hxx +// Created : Mon Aug 2 10:30:00 2004 // Author : Edward AGAPOV (eap) -// Copyright : Open CASCADE - #include "SMESH_Pattern.hxx" @@ -24,18 +41,11 @@ #include #include #include -#include -#include -#include #include #include #include #include #include -#include -#include -#include -#include #include #include #include @@ -47,6 +57,8 @@ #include "SMESHDS_Mesh.hxx" #include "SMESHDS_SubMesh.hxx" #include "SMESH_Mesh.hxx" +#include "SMESH_Block.hxx" +#include "SMESH_subMesh.hxx" #include "utilities.h" @@ -54,8 +66,6 @@ using namespace std; typedef map< const SMDS_MeshElement*, int > TNodePointIDMap; -#define SQRT_FUNC 1 - //======================================================================= //function : SMESH_Pattern //purpose : @@ -2431,164 +2441,6 @@ bool SMESH_Pattern::Apply (const TopoDS_Face& theFace, return setErrorCode( ERR_OK ); } -// ========================================================= -// class calculating coordinates of 3D points by normalized -// parameters inside the block and vice versa -// ========================================================= - -class TBlock: public math_FunctionSetWithDerivatives -{ - public: - enum TBlockShapeID { // ids of the block sub-shapes - ID_V000 = 1, ID_V100, ID_V010, ID_V110, ID_V001, ID_V101, ID_V011, ID_V111, - - ID_Ex00, ID_Ex10, ID_Ex01, ID_Ex11, - ID_E0y0, ID_E1y0, ID_E0y1, ID_E1y1, - ID_E00z, ID_E10z, ID_E01z, ID_E11z, - - ID_Fxy0, ID_Fxy1, ID_Fx0z, ID_Fx1z, ID_F0yz, ID_F1yz, - - ID_Shell - }; - static inline -bool IsVertexID( int theShapeID ) - { return ( theShapeID >= ID_V000 && theShapeID <= ID_V111 ); } - static inline bool IsEdgeID( int theShapeID ) - { return ( theShapeID >= ID_Ex00 && theShapeID <= ID_E11z ); } - static inline bool IsFaceID( int theShapeID ) - { return ( theShapeID >= ID_Fxy0 && theShapeID <= ID_F1yz ); } - - - TBlock (const TopoDS_Shell& theBlock): - myShell( theBlock ), myNbIterations(0), mySumDist(0.) {} - - bool LoadBlockShapes(const TopoDS_Vertex& theVertex000, - const TopoDS_Vertex& theVertex001, -// TopTools_IndexedMapOfShape& theShapeIDMap - TopTools_IndexedMapOfOrientedShape& theShapeIDMap ); - // add sub-shapes of theBlock to theShapeIDMap so that they get - // IDs acoording to enum TBlockShapeID - - static int GetShapeIDByParams ( const gp_XYZ& theParams ); - // define an id of the block sub-shape by point parameters - - bool VertexPoint( const int theVertexID, gp_XYZ& thePoint ) const { - if ( !IsVertexID( theVertexID )) return false; - thePoint = myPnt[ theVertexID - ID_V000 ]; return true; - } - // return vertex coordinates - - bool EdgePoint( const int theEdgeID, const gp_XYZ& theParams, gp_XYZ& thePoint ) const { - if ( !IsEdgeID( theEdgeID )) return false; - thePoint = myEdge[ theEdgeID - ID_Ex00 ].Point( theParams ); return true; - } - // return coordinates of a point on edge - - bool FacePoint( const int theFaceID, const gp_XYZ& theParams, gp_XYZ& thePoint ) const { - if ( !IsFaceID ( theFaceID )) return false; - thePoint = myFace[ theFaceID - ID_Fxy0 ].Point( theParams ); return true; - } - // return coordinates of a point on face - - bool ShellPoint( const gp_XYZ& theParams, gp_XYZ& thePoint ) const; - // return coordinates of a point in shell - - bool ComputeParameters (const gp_Pnt& thePoint, - gp_XYZ& theParams, - const int theShapeID = ID_Shell); - // compute point parameters in the block - - static void GetFaceEdgesIDs (const int faceID, vector< int >& edgeVec ); - // return edges IDs of a face in the order u0, u1, 0v, 1v - - static int GetCoordIndOnEdge (const int theEdgeID) - { return (theEdgeID < ID_E0y0) ? 1 : (theEdgeID < ID_E00z) ? 2 : 3; } - // return an index of a coordinate which varies along the edge - - static double* GetShapeCoef (const int theShapeID); - // for theShapeID( TBlockShapeID ), returns 3 coefficients used - // to compute an addition of an on-theShape point to coordinates - // of an in-shell point. If an in-shell point has parameters (Px,Py,Pz), - // then the addition of a point P is computed as P*kx*ky*kz and ki is - // defined by the returned coef like this: - // ki = (coef[i] == 0) ? 1 : (coef[i] < 0) ? 1 - Pi : Pi - - static bool IsForwardEdge (const TopoDS_Edge & theEdge, - //TopTools_IndexedMapOfShape& theShapeIDMap - TopTools_IndexedMapOfOrientedShape& theShapeIDMap) { - int v1ID = theShapeIDMap.FindIndex( TopExp::FirstVertex( theEdge ).Oriented( TopAbs_FORWARD )); - int v2ID = theShapeIDMap.FindIndex( TopExp::LastVertex( theEdge ).Oriented( TopAbs_FORWARD )); - return ( v1ID < v2ID ); - } - // Return true if an in-block parameter increases along theEdge curve - - static void Swap(double& a, double& b) { double tmp = a; a = b; b = tmp; } - - // methods of math_FunctionSetWithDerivatives - Standard_Integer NbVariables() const; - Standard_Integer NbEquations() const; - Standard_Boolean Value(const math_Vector& X,math_Vector& F) ; - Standard_Boolean Derivatives(const math_Vector& X,math_Matrix& D) ; - Standard_Boolean Values(const math_Vector& X,math_Vector& F,math_Matrix& D) ; - Standard_Integer GetStateNumber (); - - static ostream& DumpShapeID (const int theBlockShapeID, ostream& stream); - // DEBUG: dump an id of a block sub-shape - - private: - - struct TEdge { - int myCoordInd; - double myFirst; - double myLast; - Handle(Geom_Curve) myC3d; - gp_Trsf myTrsf; - double GetU( const gp_XYZ& theParams ) const; - gp_XYZ Point( const gp_XYZ& theParams ) const; - }; - - struct TFace { - // 4 edges in the order u0, u1, 0v, 1v - int myCoordInd[ 4 ]; - double myFirst [ 4 ]; - double myLast [ 4 ]; - Handle(Geom2d_Curve) myC2d [ 4 ]; - // 4 corner points in the order 00, 10, 11, 01 - gp_XY myCorner [ 4 ]; - // surface - Handle(Geom_Surface) myS; - gp_Trsf myTrsf; - gp_XY GetUV( const gp_XYZ& theParams ) const; - gp_XYZ Point( const gp_XYZ& theParams ) const; - int GetUInd() const { return myCoordInd[ 0 ]; } - int GetVInd() const { return myCoordInd[ 2 ]; } - }; - - TopoDS_Shell myShell; - // geometry: - // 8 vertices - gp_XYZ myPnt[ 8 ]; - // 12 edges - TEdge myEdge[ 12 ]; - // 6 faces - TFace myFace[ 6 ]; - - // for param computation - - int myFaceIndex; - double myFaceParam; - int myNbIterations; - double mySumDist; - - gp_XYZ myPoint; // the given point - gp_XYZ myParam; // the best parameters guess - double myValues[ 4 ]; // values computed at myParam - - typedef pair TxyzPair; - TxyzPair my3x3x3GridNodes[ 27 ]; - bool myGridComputed; -}; - //======================================================================= //function : Load //purpose : Create a pattern from the mesh built on @@ -2603,9 +2455,9 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, SMESHDS_Mesh * aMeshDS = theMesh->GetMeshDS(); // load shapes in myShapeIDMap - TBlock block( theBlock ); + SMESH_Block block; TopoDS_Vertex v1, v2; - if ( !block.LoadBlockShapes( v1, v2, myShapeIDMap )) + if ( !block.LoadBlockShapes( theBlock, v1, v2, myShapeIDMap )) return setErrorCode( ERR_LOADV_BAD_SHAPE ); // count nodes @@ -2662,8 +2514,8 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, const TopoDS_Edge& edge = TopoDS::Edge( S ); double f,l; BRep_Tool::Range( edge, f, l ); - int iCoord = TBlock::GetCoordIndOnEdge( shapeID ); - bool isForward = TBlock::IsForwardEdge( edge, myShapeIDMap ); + int iCoord = SMESH_Block::GetCoordIndOnEdge( shapeID ); + bool isForward = SMESH_Block::IsForwardEdge( edge, myShapeIDMap ); pIt = shapePoints.begin(); nIt = aSubMesh->GetNodes(); for ( ; nIt->more(); pIt++ ) @@ -2722,13 +2574,12 @@ bool SMESH_Pattern::Apply (const TopoDS_Shell& theBlock, { MESSAGE(" ::Apply(volume) " ); - TBlock block( theBlock ); - if (!findBoundaryPoints() || // bind ID to points !setShapeToMesh( theBlock )) // check theBlock is a suitable shape return false; - if (!block.LoadBlockShapes( theVertex000, theVertex001, myShapeIDMap )) // bind ID to shape + SMESH_Block block; // bind ID to shape + if (!block.LoadBlockShapes( theBlock, theVertex000, theVertex001, myShapeIDMap )) return setErrorCode( ERR_APPLV_BAD_SHAPE ); // compute XYZ of points on shapes @@ -3005,19 +2856,19 @@ void SMESH_Pattern::arrangeBoundaries (list< list< TPoint* > >& boundaryList) } // vectors of boundary direction near

gp_Vec2d v1( pPrev->myInitUV, p->myInitUV ), v2( p->myInitUV, pNext->myInitUV ); - // rotate vectors counterclockwise - v1.SetCoord( -v1.Y(), v1.X() ); - v2.SetCoord( -v2.Y(), v2.X() ); - // in-face direction - gp_Vec2d dirInFace = v1 + v2; - // for the outer boundary dirInFace should go to the right - bool reverse; - if ( bndIt == boundaryList.begin() ) // outer boundary - reverse = dirInFace.X() < 0; - else - reverse = dirInFace.X() > 0; - if ( reverse ) - boundary.reverse(); + double sqMag1 = v1.SquareMagnitude(), sqMag2 = v2.SquareMagnitude(); + if ( sqMag1 > DBL_MIN && sqMag2 > DBL_MIN ) { + double yPrev = v1.Y() / sqrt( sqMag1 ); + double yNext = v2.Y() / sqrt( sqMag2 ); + double sumY = yPrev + yNext; + bool reverse; + if ( bndIt == boundaryList.begin() ) // outer boundary + reverse = sumY > 0; + else + reverse = sumY < 0; + if ( reverse ) + boundary.reverse(); + } // Put key-point IDs of a well-oriented boundary in myKeyPointIDs (*nbKpIt) = 0; // count nb of key-points again @@ -3225,10 +3076,10 @@ bool SMESH_Pattern::findBoundaryPoints() vector< TPoint >::iterator pVecIt = myPoints.begin(); for ( int i = 0; pVecIt != myPoints.end(); pVecIt++, i++ ) { TPoint* point = &(*pVecIt); - int shapeID = TBlock::GetShapeIDByParams( point->myInitXYZ ); + int shapeID = SMESH_Block::GetShapeIDByParams( point->myInitXYZ ); getShapePoints( shapeID ).push_back( point ); // detect key-points - if ( TBlock::IsVertexID( shapeID )) + if ( SMESH_Block::IsVertexID( shapeID )) myKeyPointIDs.push_back( i ); } } @@ -3415,896 +3266,3 @@ ostream & operator <<(ostream & OS, const SMESH_Pattern::TPoint& p) return OS; } - -//======================================================================= -//function : TBlock::TEdge::GetU -//purpose : -//======================================================================= - -double TBlock::TEdge::GetU( const gp_XYZ& theParams ) const -{ - double u = theParams.Coord( myCoordInd ); - return ( 1 - u ) * myFirst + u * myLast; -} - -//======================================================================= -//function : TBlock::TEdge::Point -//purpose : -//======================================================================= - -gp_XYZ TBlock::TEdge::Point( const gp_XYZ& theParams ) const -{ - gp_XYZ p = myC3d->Value( GetU( theParams )).XYZ(); - if ( myTrsf.Form() != gp_Identity ) - myTrsf.Transforms( p ); - return p; -} - -//======================================================================= -//function : TBlock::TFace::GetUV -//purpose : -//======================================================================= - -gp_XY TBlock::TFace::GetUV( const gp_XYZ& theParams ) const -{ - gp_XY uv(0.,0.); - double dU = theParams.Coord( GetUInd() ); - double dV = theParams.Coord( GetVInd() ); - for ( int iE = 0; iE < 4; iE++ ) // loop on 4 edges - { - double Ecoef = 0, Vcoef = 0; - switch ( iE ) { - case 0: - Ecoef = ( 1 - dV ); // u0 - Vcoef = ( 1 - dU ) * ( 1 - dV ); break; // 00 - case 1: - Ecoef = dV; // u1 - Vcoef = dU * ( 1 - dV ); break; // 10 - case 2: - Ecoef = ( 1 - dU ); // 0v - Vcoef = dU * dV ; break; // 11 - case 3: - Ecoef = dU ; // 1v - Vcoef = ( 1 - dU ) * dV ; break; // 01 - default:; - } - // edge addition - double u = theParams.Coord( myCoordInd[ iE ] ); - u = ( 1 - u ) * myFirst[ iE ] + u * myLast[ iE ]; - uv += Ecoef * myC2d[ iE ]->Value( u ).XY(); - // corner addition - uv -= Vcoef * myCorner[ iE ]; - } - return uv; -} - -//======================================================================= -//function : TBlock::TFace::Point -//purpose : -//======================================================================= - -gp_XYZ TBlock::TFace::Point( const gp_XYZ& theParams ) const -{ - gp_XY uv = GetUV( theParams ); - gp_XYZ p = myS->Value( uv.X(), uv.Y() ).XYZ(); - if ( myTrsf.Form() != gp_Identity ) - myTrsf.Transforms( p ); - return p; -} - -//======================================================================= -//function : GetShapeCoef -//purpose : -//======================================================================= - -double* TBlock::GetShapeCoef (const int theShapeID) -{ - static double shapeCoef[][3] = { - // V000, V100, V010, V110 - { -1,-1,-1 }, { 1,-1,-1 }, { -1, 1,-1 }, { 1, 1,-1 }, - // V001, V101, V011, V111, - { -1,-1, 1 }, { 1,-1, 1 }, { -1, 1, 1 }, { 1, 1, 1 }, - // Ex00, Ex10, Ex01, Ex11, - { 0,-1,-1 }, { 0, 1,-1 }, { 0,-1, 1 }, { 0, 1, 1 }, - // E0y0, E1y0, E0y1, E1y1, - { -1, 0,-1 }, { 1, 0,-1 }, { -1, 0, 1 }, { 1, 0, 1 }, - // E00z, E10z, E01z, E11z, - { -1,-1, 0 }, { 1,-1, 0 }, { -1, 1, 0 }, { 1, 1, 0 }, - // Fxy0, Fxy1, Fx0z, Fx1z, F0yz, F1yz, - { 0, 0,-1 }, { 0, 0, 1 }, { 0,-1, 0 }, { 0, 1, 0 }, { -1, 0, 0 }, { 1, 0, 0 }, - // ID_Shell - { 0, 0, 0 } - }; - if ( theShapeID < ID_V000 || theShapeID > ID_F1yz ) - return shapeCoef[ ID_Shell - 1 ]; - - return shapeCoef[ theShapeID - 1 ]; -} - -//======================================================================= -//function : ShellPoint -//purpose : return coordinates of a point in shell -//======================================================================= - -bool TBlock::ShellPoint( const gp_XYZ& theParams, gp_XYZ& thePoint ) const -{ - thePoint.SetCoord( 0., 0., 0. ); - for ( int shapeID = ID_V000; shapeID < ID_Shell; shapeID++ ) - { - // coef - double* coefs = GetShapeCoef( shapeID ); - double k = 1; - for ( int iCoef = 0; iCoef < 3; iCoef++ ) { - if ( coefs[ iCoef ] != 0 ) { - if ( coefs[ iCoef ] < 0 ) - k *= ( 1. - theParams.Coord( iCoef + 1 )); - else - k *= theParams.Coord( iCoef + 1 ); - } - } - // point on a shape - gp_XYZ Ps; - if ( shapeID < ID_Ex00 ) // vertex - VertexPoint( shapeID, Ps ); - else if ( shapeID < ID_Fxy0 ) { // edge - EdgePoint( shapeID, theParams, Ps ); - k = -k; - } else // face - FacePoint( shapeID, theParams, Ps ); - - thePoint += k * Ps; - } - return true; -} - -//======================================================================= -//function : NbVariables -//purpose : -//======================================================================= - -Standard_Integer TBlock::NbVariables() const -{ - return 3; -} - -//======================================================================= -//function : NbEquations -//purpose : -//======================================================================= - -Standard_Integer TBlock::NbEquations() const -{ - return 1; -} - -//======================================================================= -//function : Value -//purpose : -//======================================================================= - -Standard_Boolean TBlock::Value(const math_Vector& theXYZ, math_Vector& theFxyz) -{ - gp_XYZ P, params( theXYZ(1), theXYZ(2), theXYZ(3) ); - if ( params.IsEqual( myParam, DBL_MIN )) { // same param - theFxyz( 1 ) = myValues[ 0 ]; - } - else { - ShellPoint( params, P ); - gp_Vec dP( P - myPoint ); - theFxyz(1) = SQRT_FUNC ? dP.SquareMagnitude() : dP.Magnitude(); - } - return true; -} - -//======================================================================= -//function : Derivatives -//purpose : -//======================================================================= - -Standard_Boolean TBlock::Derivatives(const math_Vector& XYZ,math_Matrix& Df) -{ - MESSAGE( "TBlock::Derivatives()"); - math_Vector F(1,3); - return Values(XYZ,F,Df); -} - -//======================================================================= -//function : Values -//purpose : -//======================================================================= - -Standard_Boolean TBlock::Values(const math_Vector& theXYZ, - math_Vector& theFxyz, - math_Matrix& theDf) -{ -// MESSAGE( endl<<"TBlock::Values( "< DBL_MIN ) - dPi /= mag; - drv[ iP - 1 ] = dPi; - } - for ( int iP = 0; iP < 3; iP++ ) { - if ( iP == myFaceIndex ) - theDf( 1, iP + 1 ) = myFaceParam; - else { - // like IntAna_IntConicQuad::Perform (const gp_Lin& L, const gp_Pln& P) - // where L is (P -> myPoint), P is defined by the 2 other derivative direction - int iPrev = ( iP ? iP - 1 : 2 ); - int iNext = ( iP == 2 ? 0 : iP + 1 ); - gp_Vec plnNorm = drv[ iPrev ].Crossed( drv [ iNext ] ); - double Direc = plnNorm * drv[ iP ]; - if ( Abs(Direc) <= DBL_MIN ) - theDf( 1, iP + 1 ) = dP * drv[ iP ]; - else { - double Dis = plnNorm * P - plnNorm * myPoint; - theDf( 1, iP + 1 ) = Dis/Direc; - } - } - } - //myNbIterations +=3; // how many time call ShellPoint() - - // store better values - myParam = params; - myValues[0]= theFxyz(1); - myValues[1]= theDf(1,1); - myValues[2]= theDf(1,2); - myValues[3]= theDf(1,3); - -// SCRUTE( theFxyz(1) ); -// SCRUTE( theDf( 1,1 )); -// SCRUTE( theDf( 1,2 )); -// SCRUTE( theDf( 1,3 )); - } - - return true; -} - -//======================================================================= -//function : ComputeParameters -//purpose : compute point parameters in the block -//======================================================================= - -bool TBlock::ComputeParameters(const gp_Pnt& thePoint, - gp_XYZ& theParams, - const int theShapeID) -{ -// MESSAGE( endl<<"TBlock::ComputeParameters( " -// < zero ) { - par = v0P.Dot( v01 ) / len2; - if ( par < 0 || par > 1 ) { - needGrid = true; - break; - } - } - start( iParam ) += par; - } - start( iParam ) /= 4.; - } - if ( needGrid ) { - // compute nodes of 3 x 3 x 3 grid - int iNode = 0; - for ( double x = 0.25; x < 0.9; x += 0.25 ) - for ( double y = 0.25; y < 0.9; y += 0.25 ) - for ( double z = 0.25; z < 0.9; z += 0.25 ) { - TxyzPair & prmPtn = my3x3x3GridNodes[ iNode++ ]; - prmPtn.first.SetCoord( x, y, z ); - ShellPoint( prmPtn.first, prmPtn.second ); - } - myGridComputed = true; - } - } - if ( myGridComputed ) { - double minDist = DBL_MAX; - gp_XYZ* bestParam = 0; - for ( int iNode = 0; iNode < 27; iNode++ ) { - TxyzPair & prmPtn = my3x3x3GridNodes[ iNode ]; - double dist = ( thePoint.XYZ() - prmPtn.second ).SquareModulus(); - if ( dist < minDist ) { - minDist = dist; - bestParam = & prmPtn.first; - } - } - start( 1 ) = bestParam->X(); - start( 2 ) = bestParam->Y(); - start( 3 ) = bestParam->Z(); - } - - int myFaceIndex = -1; - if ( isOnFace ) { - // put a point on the face - for ( int iCoord = 0; iCoord < 3; iCoord++ ) - if ( coef[ iCoord ] ) { - myFaceIndex = iCoord; - myFaceParam = ( coef[ myFaceIndex ] < 0.5 ) ? 0.0 : 1.0; - start( iCoord + 1 ) = myFaceParam; - } - } - math_Vector low ( 1, 3, 0.0 ); - math_Vector up ( 1, 3, 1.0 ); - math_Vector tol ( 1, 3, 1e-4 ); - math_FunctionSetRoot paramSearch( *this, tol ); - - int nbLoops = 0; - while ( myValues[0] > 1e-1 && nbLoops++ < 10 ) { - paramSearch.Perform ( *this, start, low, up ); - if ( !paramSearch.IsDone() ) { - //MESSAGE( " !paramSearch.IsDone() " ); - } - else { - //MESSAGE( " NB ITERATIONS: " << paramSearch.NbIterations() ); - } - start( 1 ) = myParam.X(); - start( 2 ) = myParam.Y(); - start( 3 ) = myParam.Z(); - //MESSAGE( "Distance: " << ( SQRT_FUNC ? sqrt(myValues[0]) : myValues[0] )); - } -// MESSAGE( endl << myParam.X() << " " << myParam.Y() << " " << myParam.Z() << endl); -// mySumDist += myValues[0]; -// MESSAGE( " TOTAL NB ITERATIONS: " << myNbIterations << -// " DIST: " << ( SQRT_FUNC ? sqrt(mySumDist) : mySumDist )); - - - theParams = myParam; - - return true; -} - -//======================================================================= -//function : GetStateNumber -//purpose : -//======================================================================= - -Standard_Integer TBlock::GetStateNumber () -{ -// MESSAGE( endl<<"TBlock::GetStateNumber( "< 26 || id < 0 ) { - MESSAGE( "GetShapeIDByParams() = " << id - <<" "<< theCoord.X() <<" "<< theCoord.Y() <<" "<< theCoord.Z() ); - } - - return id + 1; // shape ids start at 1 -} - -//======================================================================= -//function : LoadBlockShapes -//purpose : add sub-shapes of theBlock to theShapeIDMap so that they get -// IDs acoording to enum TBlockShapeID -//======================================================================= - -bool TBlock::LoadBlockShapes(const TopoDS_Vertex& theVertex000, - const TopoDS_Vertex& theVertex001, -// TopTools_IndexedMapOfShape& theShapeIDMap - TopTools_IndexedMapOfOrientedShape& theShapeIDMap ) -{ - MESSAGE(" ::LoadBlockShapes()"); - myGridComputed = false; - - // 6 vertices - TopoDS_Shape V000, V100, V010, V110, V001, V101, V011, V111; - // 12 edges - TopoDS_Shape Ex00, Ex10, Ex01, Ex11; - TopoDS_Shape E0y0, E1y0, E0y1, E1y1; - TopoDS_Shape E00z, E10z, E01z, E11z; - // 6 faces - TopoDS_Shape Fxy0, Fx0z, F0yz, Fxy1, Fx1z, F1yz; - - // nb of faces bound to a vertex in TopTools_IndexedDataMapOfShapeListOfShape - // filled by TopExp::MapShapesAndAncestors() - const int NB_FACES_BY_VERTEX = 6; - - TopTools_IndexedDataMapOfShapeListOfShape vfMap; - TopExp::MapShapesAndAncestors( myShell, TopAbs_VERTEX, TopAbs_FACE, vfMap ); - if ( vfMap.Extent() != 8 ) { - MESSAGE(" Wrong nb of vertices in the block: " << vfMap.Extent() ); - return false; - } - - V000 = theVertex000; - V001 = theVertex001; - - if ( V000.IsNull() ) { - // find vertex 000 - the one with smallest coordinates - double minVal = DBL_MAX, minX, val; - for ( int i = 1; i <= 8; i++ ) { - const TopoDS_Vertex& v = TopoDS::Vertex( vfMap.FindKey( i )); - gp_Pnt P = BRep_Tool::Pnt( v ); - val = P.X() + P.Y() + P.Z(); - if ( val < minVal || ( val == minVal && P.X() < minX )) { - V000 = v; - minVal = val; - minX = P.X(); - } - } - // find vertex 001 - the one on the most vertical edge passing through V000 - TopTools_IndexedDataMapOfShapeListOfShape veMap; - TopExp::MapShapesAndAncestors( myShell, TopAbs_VERTEX, TopAbs_EDGE, veMap ); - gp_Vec dir001 = gp::DZ(); - gp_Pnt p000 = BRep_Tool::Pnt( TopoDS::Vertex( V000 )); - double maxVal = -DBL_MAX; - TopTools_ListIteratorOfListOfShape eIt ( veMap.FindFromKey( V000 )); - for ( ; eIt.More(); eIt.Next() ) { - const TopoDS_Edge& e = TopoDS::Edge( eIt.Value() ); - TopoDS_Vertex v = TopExp::FirstVertex( e ); - if ( v.IsSame( V000 )) - v = TopExp::LastVertex( e ); - val = dir001 * gp_Vec( p000, BRep_Tool::Pnt( v )).Normalized(); - if ( val > maxVal ) { - V001 = v; - maxVal = val; - } - } - } - - // find the bottom (Fxy0), Fx0z and F0yz faces - - const TopTools_ListOfShape& f000List = vfMap.FindFromKey( V000 ); - const TopTools_ListOfShape& f001List = vfMap.FindFromKey( V001 ); - if (f000List.Extent() != NB_FACES_BY_VERTEX || - f001List.Extent() != NB_FACES_BY_VERTEX ) { - MESSAGE(" LoadBlockShapes() " << f000List.Extent() << " " << f001List.Extent()); - return false; - } - TopTools_ListIteratorOfListOfShape f001It, f000It ( f000List ); - int i, j, iFound1, iFound2; - for ( j = 0; f000It.More(); f000It.Next(), j++ ) - { - if ( NB_FACES_BY_VERTEX == 6 && j % 2 ) continue; // each face encounters twice - const TopoDS_Shape& F = f000It.Value(); - for ( i = 0, f001It.Initialize( f001List ); f001It.More(); f001It.Next(), i++ ) { - if ( NB_FACES_BY_VERTEX == 6 && i % 2 ) continue; // each face encounters twice - if ( F.IsSame( f001It.Value() )) - break; - } - if ( f001It.More() ) // Fx0z or F0yz found - if ( Fx0z.IsNull() ) { - Fx0z = F; - iFound1 = i; - } else { - F0yz = F; - iFound2 = i; - } - else // F is the bottom face - Fxy0 = F; - } - if ( Fxy0.IsNull() || Fx0z.IsNull() || F0yz.IsNull() ) { - MESSAGE( Fxy0.IsNull() <<" "<< Fx0z.IsNull() <<" "<< F0yz.IsNull() ); - return false; - } - - // choose the top face (Fxy1) - for ( i = 0, f001It.Initialize( f001List ); f001It.More(); f001It.Next(), i++ ) { - if ( NB_FACES_BY_VERTEX == 6 && i % 2 ) continue; // each face encounters twice - if ( i != iFound1 && i != iFound2 ) - break; - } - Fxy1 = f001It.Value(); - if ( Fxy1.IsNull() ) { - MESSAGE(" LoadBlockShapes() error "); - return false; - } - - // find bottom edges and veritices - list< TopoDS_Edge > eList; - list< int > nbVertexInWires; - getOrderedEdges( TopoDS::Face( Fxy0 ), TopoDS::Vertex( V000 ), eList, nbVertexInWires ); - if ( nbVertexInWires.size() != 1 || nbVertexInWires.front() != 4 ) { - MESSAGE(" LoadBlockShapes() error "); - return false; - } - list< TopoDS_Edge >::iterator elIt = eList.begin(); - for ( i = 0; elIt != eList.end(); elIt++, i++ ) - switch ( i ) { - case 0: E0y0 = *elIt; V010 = TopExp::LastVertex( *elIt, true ); break; - case 1: Ex10 = *elIt; V110 = TopExp::LastVertex( *elIt, true ); break; - case 2: E1y0 = *elIt; V100 = TopExp::LastVertex( *elIt, true ); break; - case 3: Ex00 = *elIt; break; - default:; - } - if ( i != 4 || E0y0.IsNull() || Ex10.IsNull() || E1y0.IsNull() || Ex00.IsNull() ) { - MESSAGE(" LoadBlockShapes() error, eList.size()=" << eList.size()); - return false; - } - - - // find top edges and veritices - eList.clear(); - getOrderedEdges( TopoDS::Face( Fxy1 ), TopoDS::Vertex( V001 ), eList, nbVertexInWires ); - if ( nbVertexInWires.size() != 1 || nbVertexInWires.front() != 4 ) { - MESSAGE(" LoadBlockShapes() error "); - return false; - } - for ( i = 0, elIt = eList.begin(); elIt != eList.end(); elIt++, i++ ) - switch ( i ) { - case 0: Ex01 = *elIt; V101 = TopExp::LastVertex( *elIt, true ); break; - case 1: E1y1 = *elIt; V111 = TopExp::LastVertex( *elIt, true ); break; - case 2: Ex11 = *elIt; V011 = TopExp::LastVertex( *elIt, true ); break; - case 3: E0y1 = *elIt; break; - default:; - } - if ( i != 4 || Ex01.IsNull() || E1y1.IsNull() || Ex11.IsNull() || E0y1.IsNull() ) { - MESSAGE(" LoadBlockShapes() error, eList.size()=" << eList.size()); - return false; - } - - // swap Fx0z and F0yz if necessary - TopExp_Explorer exp( Fx0z, TopAbs_VERTEX ); - for ( ; exp.More(); exp.Next() ) // Fx0z shares V101 and V100 - if ( V101.IsSame( exp.Current() ) || V100.IsSame( exp.Current() )) - break; // V101 or V100 found - if ( !exp.More() ) { // not found - TopoDS_Shape f = Fx0z; Fx0z = F0yz; F0yz = f; - } - - // find Fx1z and F1yz faces - const TopTools_ListOfShape& f111List = vfMap.FindFromKey( V111 ); - const TopTools_ListOfShape& f110List = vfMap.FindFromKey( V110 ); - if (f111List.Extent() != NB_FACES_BY_VERTEX || - f110List.Extent() != NB_FACES_BY_VERTEX ) { - MESSAGE(" LoadBlockShapes() " << f111List.Extent() << " " << f110List.Extent()); - return false; - } - TopTools_ListIteratorOfListOfShape f111It, f110It ( f110List); - for ( j = 0 ; f110It.More(); f110It.Next(), j++ ) { - if ( NB_FACES_BY_VERTEX == 6 && j % 2 ) continue; // each face encounters twice - const TopoDS_Shape& F = f110It.Value(); - for ( i = 0, f111It.Initialize( f111List ); f111It.More(); f111It.Next(), i++ ) { - if ( NB_FACES_BY_VERTEX == 6 && i % 2 ) continue; // each face encounters twice - if ( F.IsSame( f111It.Value() )) { // Fx1z or F1yz found - if ( Fx1z.IsNull() ) - Fx1z = F; - else - F1yz = F; - } - } - } - if ( Fx1z.IsNull() || F1yz.IsNull() ) { - MESSAGE(" LoadBlockShapes() error "); - return false; - } - - // swap Fx1z and F1yz if necessary - for ( exp.Init( Fx1z, TopAbs_VERTEX ); exp.More(); exp.Next() ) - if ( V010.IsSame( exp.Current() ) || V011.IsSame( exp.Current() )) - break; - if ( !exp.More() ) { - TopoDS_Shape f = Fx1z; Fx1z = F1yz; F1yz = f; - } - - // find vertical edges - for ( exp.Init( Fx0z, TopAbs_EDGE ); exp.More(); exp.Next() ) { - const TopoDS_Edge& edge = TopoDS::Edge( exp.Current() ); - const TopoDS_Shape& vFirst = TopExp::FirstVertex( edge, true ); - if ( vFirst.IsSame( V001 )) - E00z = edge; - else if ( vFirst.IsSame( V100 )) - E10z = edge; - } - if ( E00z.IsNull() || E10z.IsNull() ) { - MESSAGE(" LoadBlockShapes() error "); - return false; - } - for ( exp.Init( Fx1z, TopAbs_EDGE ); exp.More(); exp.Next() ) { - const TopoDS_Edge& edge = TopoDS::Edge( exp.Current() ); - const TopoDS_Shape& vFirst = TopExp::FirstVertex( edge, true ); - if ( vFirst.IsSame( V111 )) - E11z = edge; - else if ( vFirst.IsSame( V010 )) - E01z = edge; - } - if ( E01z.IsNull() || E11z.IsNull() ) { - MESSAGE(" LoadBlockShapes() error "); - return false; - } - - // load shapes in theShapeIDMap - - theShapeIDMap.Clear(); - - theShapeIDMap.Add(V000.Oriented( TopAbs_FORWARD )); - theShapeIDMap.Add(V100.Oriented( TopAbs_FORWARD )); - theShapeIDMap.Add(V010.Oriented( TopAbs_FORWARD )); - theShapeIDMap.Add(V110.Oriented( TopAbs_FORWARD )); - theShapeIDMap.Add(V001.Oriented( TopAbs_FORWARD )); - theShapeIDMap.Add(V101.Oriented( TopAbs_FORWARD )); - theShapeIDMap.Add(V011.Oriented( TopAbs_FORWARD )); - theShapeIDMap.Add(V111.Oriented( TopAbs_FORWARD )); - - theShapeIDMap.Add(Ex00); - theShapeIDMap.Add(Ex10); - theShapeIDMap.Add(Ex01); - theShapeIDMap.Add(Ex11); - - theShapeIDMap.Add(E0y0); - theShapeIDMap.Add(E1y0); - theShapeIDMap.Add(E0y1); - theShapeIDMap.Add(E1y1); - - theShapeIDMap.Add(E00z); - theShapeIDMap.Add(E10z); - theShapeIDMap.Add(E01z); - theShapeIDMap.Add(E11z); - - theShapeIDMap.Add(Fxy0); - theShapeIDMap.Add(Fxy1); - theShapeIDMap.Add(Fx0z); - theShapeIDMap.Add(Fx1z); - theShapeIDMap.Add(F0yz); - theShapeIDMap.Add(F1yz); - - theShapeIDMap.Add(myShell); - - if ( theShapeIDMap.Extent() != 27 ) { - MESSAGE("LoadBlockShapes() " << theShapeIDMap.Extent() ); - return false; - } - - // store shapes geometry - for ( int shapeID = 1; shapeID < theShapeIDMap.Extent(); shapeID++ ) - { - const TopoDS_Shape& S = theShapeIDMap( shapeID ); - switch ( S.ShapeType() ) - { - case TopAbs_VERTEX: { - - if ( shapeID > ID_V111 ) { - MESSAGE(" shapeID =" << shapeID ); - return false; - } - myPnt[ shapeID - ID_V000 ] = - BRep_Tool::Pnt( TopoDS::Vertex( S )).XYZ(); - break; - } - case TopAbs_EDGE: { - - const TopoDS_Edge& edge = TopoDS::Edge( S ); - if ( shapeID < ID_Ex00 || shapeID > ID_E11z || edge.IsNull() ) { - MESSAGE(" shapeID =" << shapeID ); - return false; - } - TEdge& tEdge = myEdge[ shapeID - ID_Ex00 ]; - tEdge.myCoordInd = GetCoordIndOnEdge( shapeID ); - TopLoc_Location loc; - tEdge.myC3d = BRep_Tool::Curve( edge, loc, tEdge.myFirst, tEdge.myLast ); - if ( !IsForwardEdge( edge, theShapeIDMap )) - Swap( tEdge.myFirst, tEdge.myLast ); - tEdge.myTrsf = loc; - break; - } - case TopAbs_FACE: { - - const TopoDS_Face& face = TopoDS::Face( S ); - if ( shapeID < ID_Fxy0 || shapeID > ID_F1yz || face.IsNull() ) { - MESSAGE(" shapeID =" << shapeID ); - return false; - } - TFace& tFace = myFace[ shapeID - ID_Fxy0 ]; - // pcurves - vector< int > edgeIdVec(4, -1); - GetFaceEdgesIDs( shapeID, edgeIdVec ); - for ( int iE = 0; iE < 4; iE++ ) // loop on 4 edges - { - const TopoDS_Edge& edge = TopoDS::Edge( theShapeIDMap( edgeIdVec[ iE ])); - tFace.myCoordInd[ iE ] = GetCoordIndOnEdge( edgeIdVec[ iE ] ); - tFace.myC2d[ iE ] = - BRep_Tool::CurveOnSurface( edge, face, tFace.myFirst[iE], tFace.myLast[iE] ); - if ( !IsForwardEdge( edge, theShapeIDMap )) - Swap( tFace.myFirst[ iE ], tFace.myLast[ iE ] ); - } - // 2d corners - tFace.myCorner[ 0 ] = tFace.myC2d[ 0 ]->Value( tFace.myFirst[0] ).XY(); - tFace.myCorner[ 1 ] = tFace.myC2d[ 0 ]->Value( tFace.myLast[0] ).XY(); - tFace.myCorner[ 2 ] = tFace.myC2d[ 1 ]->Value( tFace.myLast[1] ).XY(); - tFace.myCorner[ 3 ] = tFace.myC2d[ 1 ]->Value( tFace.myFirst[1] ).XY(); - // sufrace - TopLoc_Location loc; - tFace.myS = BRep_Tool::Surface( face, loc ); - tFace.myTrsf = loc; - break; - } - default: break; - } - } // loop on shapes in theShapeIDMap - - return true; -} - -//======================================================================= -//function : GetFaceEdgesIDs -//purpose : return edges IDs in the order u0, u1, 0v, 1v -// u0 means "|| u, v == 0" -//======================================================================= - -void TBlock::GetFaceEdgesIDs (const int faceID, vector< int >& edgeVec ) -{ - switch ( faceID ) { - case ID_Fxy0: - edgeVec[ 0 ] = ID_Ex00; - edgeVec[ 1 ] = ID_Ex10; - edgeVec[ 2 ] = ID_E0y0; - edgeVec[ 3 ] = ID_E1y0; - break; - case ID_Fxy1: - edgeVec[ 0 ] = ID_Ex01; - edgeVec[ 1 ] = ID_Ex11; - edgeVec[ 2 ] = ID_E0y1; - edgeVec[ 3 ] = ID_E1y1; - break; - case ID_Fx0z: - edgeVec[ 0 ] = ID_Ex00; - edgeVec[ 1 ] = ID_Ex01; - edgeVec[ 2 ] = ID_E00z; - edgeVec[ 3 ] = ID_E10z; - break; - case ID_Fx1z: - edgeVec[ 0 ] = ID_Ex10; - edgeVec[ 1 ] = ID_Ex11; - edgeVec[ 2 ] = ID_E01z; - edgeVec[ 3 ] = ID_E11z; - break; - case ID_F0yz: - edgeVec[ 0 ] = ID_E0y0; - edgeVec[ 1 ] = ID_E0y1; - edgeVec[ 2 ] = ID_E00z; - edgeVec[ 3 ] = ID_E01z; - break; - case ID_F1yz: - edgeVec[ 0 ] = ID_E1y0; - edgeVec[ 1 ] = ID_E1y1; - edgeVec[ 2 ] = ID_E10z; - edgeVec[ 3 ] = ID_E11z; - break; - default: - MESSAGE(" GetFaceEdgesIDs(), wrong face ID: " << faceID ); - } -} diff --git a/src/SMESH/SMESH_Pattern.hxx b/src/SMESH/SMESH_Pattern.hxx index b658a2502..9358fae47 100644 --- a/src/SMESH/SMESH_Pattern.hxx +++ b/src/SMESH/SMESH_Pattern.hxx @@ -30,7 +30,6 @@ #include #include -//#include #include #include #include diff --git a/src/SMESH/SMESH_subMesh.cxx b/src/SMESH/SMESH_subMesh.cxx index 89e9e2684..238bd22d9 100644 --- a/src/SMESH/SMESH_subMesh.cxx +++ b/src/SMESH/SMESH_subMesh.cxx @@ -32,16 +32,20 @@ using namespace std; #include "SMESH_Mesh.hxx" #include "SMESH_Hypothesis.hxx" #include "SMESH_Algo.hxx" + #include "utilities.h" #include "OpUtil.hxx" +#include + #include -#include +#include +#include #include #include +#include + #include -#include -#include #ifdef _DEBUG_ #include @@ -550,6 +554,43 @@ SMESH_Hypothesis::Hypothesis_Status if ( !_meshDS->AddHypothesis(_subShape, anHyp)) return SMESH_Hypothesis::HYP_ALREADY_EXIST; + + // Serve Propagation of 1D hypothesis + if (event == ADD_HYP) { + bool isPropagationOk = true; + string hypName = anHyp->GetName(); + + if (hypName == "Propagation") { + if (_subShape.ShapeType() == TopAbs_EDGE) { + isPropagationOk = _father->BuildPropagationChain(_subShape); + } else { + TopExp_Explorer exp (_subShape, TopAbs_EDGE); + TopTools_MapOfShape aMap; + for (; exp.More(); exp.Next()) { + if (aMap.Add(exp.Current())) { + if (!_father->BuildPropagationChain(exp.Current())) { + isPropagationOk = false; + } + } + } + } + } else if (anHyp->GetDim() == 1) { // Only 1D hypothesis can be propagated + if (_subShape.ShapeType() == TopAbs_EDGE) { + TopoDS_Shape aMainEdge; + if (_father->IsPropagatedHypothesis(_subShape, aMainEdge)) { + isPropagationOk = _father->RebuildPropagationChains(); + } else if (_father->IsPropagationHypothesis(_subShape)) { + isPropagationOk = _father->BuildPropagationChain(_subShape); + } else { + } + } + } else { + } + + if (!isPropagationOk && ret < SMESH_Hypothesis::HYP_CONCURENT) { + ret = SMESH_Hypothesis::HYP_CONCURENT; + } + } // Serve Propagation of 1D hypothesis } // -------------------------- @@ -559,6 +600,51 @@ SMESH_Hypothesis::Hypothesis_Status { if (!_meshDS->RemoveHypothesis(_subShape, anHyp)) return SMESH_Hypothesis::HYP_OK; // nothing changes + + // Serve Propagation of 1D hypothesis + if (event == REMOVE_HYP) { + bool isPropagationOk = true; + string hypName = anHyp->GetName(); + + if (hypName == "Propagation") { + if (_subShape.ShapeType() == TopAbs_EDGE) { + if (!_father->RemovePropagationChain(_subShape)) { + return SMESH_Hypothesis::HYP_UNKNOWN_FATAL; + } + // rebuild propagation chains, because removing one + // chain can resolve concurention, existing before + isPropagationOk = _father->RebuildPropagationChains(); + } else { + TopExp_Explorer exp (_subShape, TopAbs_EDGE); + TopTools_MapOfShape aMap; + for (; exp.More(); exp.Next()) { + if (aMap.Add(exp.Current())) { + if (!_father->RemovePropagationChain(exp.Current())) { + return SMESH_Hypothesis::HYP_UNKNOWN_FATAL; + } + } + } + // rebuild propagation chains, because removing one + // chain can resolve concurention, existing before + if (!_father->RebuildPropagationChains()) { + isPropagationOk = false; + } + } + } else { // if (hypName == "Propagation") + if (anHyp->GetDim() == 1) // Only 1D hypothesis can be propagated + { + if (_subShape.ShapeType() == TopAbs_EDGE) { + isPropagationOk = _father->RebuildPropagationChains(); + if (!isPropagationOk && ret < SMESH_Hypothesis::HYP_CONCURENT) + ret = SMESH_Hypothesis::HYP_CONCURENT; + } + } + } + + if (!isPropagationOk && ret < SMESH_Hypothesis::HYP_CONCURENT) { + ret = SMESH_Hypothesis::HYP_CONCURENT; + } + } // Serve Propagation of 1D hypothesis } // ------------------ @@ -843,22 +929,9 @@ SMESH_Hypothesis::Hypothesis_Status ASSERT(0); break; } - // ---------------------------------------- - // check concurent hypotheses on ansestors - // ---------------------------------------- - if (ret < SMESH_Hypothesis::HYP_CONCURENT && - (event == ADD_FATHER_HYP || - event == ADD_FATHER_ALGO || - event == REMOVE_FATHER_HYP || - event == REMOVE_FATHER_ALGO || - event == REMOVE_ALGO || - event == REMOVE_HYP)) - { - ret = CheckConcurentHypothesis( anHyp->GetType() ); - } if ((_algoState != oldAlgoState) || modifiedHyp) - int retc = ComputeStateEngine(MODIF_ALGO_STATE); + ComputeStateEngine(MODIF_ALGO_STATE); return ret; } diff --git a/src/SMESH/SMESH_subMesh.hxx b/src/SMESH/SMESH_subMesh.hxx index 307ddf2c9..8669c22f0 100644 --- a/src/SMESH/SMESH_subMesh.hxx +++ b/src/SMESH/SMESH_subMesh.hxx @@ -123,6 +123,8 @@ class SMESH_subMesh // return true if theHypothesis can be used to mesh me: // its shape type is checked + SMESH_Hypothesis::Hypothesis_Status CheckConcurentHypothesis (const int theHypType); + // check if there are several applicable hypothesis on fathers protected: void InsertDependence(const TopoDS_Shape aSubShape); @@ -150,9 +152,6 @@ class SMESH_subMesh const TopoDS_Shape& theCollection); // Apply theAlgo to all subshapes in theCollection - SMESH_Hypothesis::Hypothesis_Status CheckConcurentHypothesis (const int theHypType); - // check if there are several applicable hypothesis on fathers - const SMESH_Hypothesis* GetSimilarAttached(const TopoDS_Shape& theShape, const SMESH_Hypothesis * theHyp, const int theHypType = 0); diff --git a/src/SMESHGUI/Makefile.in b/src/SMESHGUI/Makefile.in index 973071422..e3a137822 100644 --- a/src/SMESHGUI/Makefile.in +++ b/src/SMESHGUI/Makefile.in @@ -66,6 +66,7 @@ LIB_SRC = SMESHGUI.cxx \ SMESHGUI_RemoveNodesDlg.cxx \ SMESHGUI_RemoveElementsDlg.cxx \ SMESHGUI_MeshInfosDlg.cxx \ + SMESHGUI_StandardMeshInfosDlg.cxx \ SMESHGUI_Preferences_ColorDlg.cxx \ SMESHGUI_Preferences_ScalarBarDlg.cxx \ SMESHGUI_Preferences_SelectionDlg.cxx \ @@ -119,6 +120,7 @@ LIB_MOC = \ SMESHGUI_RemoveNodesDlg.h \ SMESHGUI_RemoveElementsDlg.h \ SMESHGUI_MeshInfosDlg.h \ + SMESHGUI_StandardMeshInfosDlg.h \ SMESHGUI_Preferences_ColorDlg.h \ SMESHGUI_Preferences_ScalarBarDlg.h \ SMESHGUI_Preferences_SelectionDlg.h \ diff --git a/src/SMESHGUI/SMESHGUI.cxx b/src/SMESHGUI/SMESHGUI.cxx index 49baea8a3..78f27d222 100644 --- a/src/SMESHGUI/SMESHGUI.cxx +++ b/src/SMESHGUI/SMESHGUI.cxx @@ -34,6 +34,7 @@ #include "SMESHGUI_RemoveNodesDlg.h" #include "SMESHGUI_RemoveElementsDlg.h" #include "SMESHGUI_MeshInfosDlg.h" +#include "SMESHGUI_StandardMeshInfosDlg.h" #include "SMESHGUI_Preferences_ColorDlg.h" #include "SMESHGUI_Preferences_ScalarBarDlg.h" #include "SMESHGUI_Preferences_SelectionDlg.h" @@ -626,6 +627,16 @@ namespace{ void OnEditDelete() { + // VSR 17/11/04: check if all objects selected belong to SMESH component --> start + QString aParentComponent = ((SALOMEGUI_Desktop*)QAD_Application::getDesktop())->getComponentFromSelection(); + if ( aParentComponent != QAD_Application::getDesktop()->getActiveComponent() ) { + QAD_MessageBox::warn1 ( QAD_Application::getDesktop(), + QObject::tr("ERR_ERROR"), + QObject::tr("NON_SMESH_OBJECTS_SELECTED").arg(QAD_Application::getDesktop()->getComponentUserName( "SMESH" )), + QObject::tr("BUT_OK") ); + return; + } + // VSR 17/11/04: check if all objects selected belong to SMESH component <-- finish if (QAD_MessageBox::warn2 (QAD_Application::getDesktop(), QObject::tr("SMESH_WRN_WARNING"), @@ -712,32 +723,35 @@ namespace{ * */ //============================================================================= -class CustomItem:public QCustomMenuItem +class CustomItem : public QCustomMenuItem { - public: - CustomItem(const QString & s, const QFont & f):string(s), font(f) - { - }; - ~CustomItem() +public: + CustomItem(const QString& s, const QFont& f) : myString(s), myFont(f) {} + ~CustomItem() {} + + void paint(QPainter* p, const QColorGroup& cg, bool act, bool /*enabled*/, int x, int y, int w, int h) { + p->save(); + p->fillRect( x, y, w, h, act ? cg.highlight() : cg.mid() ); + p->setPen( act ? cg.highlightedText() : cg.buttonText() ); + p->setFont( myFont ); + p->drawText( x, y, w, h, AlignHCenter | AlignVCenter | ShowPrefix | DontClip | SingleLine, myString ); + p->restore(); } - void paint(QPainter * p, const QColorGroup & /*cg */ , bool /*act */ , - bool /*enabled */ , int x, int y, int w, int h) + QSize sizeHint() { - p->setFont(font); - p->drawText(x, y, w, h, - AlignHCenter | AlignVCenter | ShowPrefix | DontClip, string); + return QFontMetrics( myFont ).size( AlignHCenter | AlignVCenter | ShowPrefix | DontClip | SingleLine, myString ); } - QSize sizeHint() + bool fullSpan() const { - return QFontMetrics(font). - size(AlignHCenter | AlignVCenter | ShowPrefix | DontClip, string); + return true; } - private: - QString string; - QFont font; + +private: + QString myString; + QFont myFont; }; //============================================================================= @@ -1542,6 +1556,29 @@ bool SMESHGUI::OnGUIEvent(int theCommandID, QAD_Desktop * parent) break; } + case 902: // STANDARD MESH INFOS + { + EmitSignalDeactivateDialog(); + SALOME_Selection *Sel = + SALOME_Selection::Selection(myActiveStudy->getSelection()); + if ( Sel->IObjectCount() > 1 ) { // a dlg for each IO + SALOME_ListIO IOs; IOs = Sel->StoredIObjects(); // list copy + SALOME_ListIteratorOfListIO It (IOs); + for ( ; It.More(); It.Next() ) { + Sel->ClearIObjects(); + Sel->AddIObject( It.Value() ); + SMESHGUI_StandardMeshInfosDlg *aDlg = new SMESHGUI_StandardMeshInfosDlg(parent, "", false); + } + // restore selection + Sel->ClearIObjects(); + for (It.Initialize( IOs ) ; It.More(); It.Next() ) + Sel->AddIObject( It.Value() ); + } + else + SMESHGUI_StandardMeshInfosDlg *aDlg = new SMESHGUI_StandardMeshInfosDlg(parent, "", false); + break; + } + case 1001: // AUTOMATIC UPDATE PREFERENCES { parent->menuBar()->setItemChecked(1001, !parent->menuBar()->isItemChecked(1001)); @@ -2246,7 +2283,7 @@ bool SMESHGUI::CustomPopup(QAD_Desktop* parent, QPopupMenu* popup, const QString if ( topItem >= 0 ) { if ( theParent == "Viewer" ) { // set bold font for popup menu's TopLabel item (Viewer popup) - QFont fnt = QApplication::font(); fnt.setBold( TRUE ); + QFont fnt = popup->font(); fnt.setBold( TRUE ); popup->removeItem( QAD_TopLabel_Popup_ID ); popup->insertItem( new CustomItem( QString( IObject->getName() ), fnt ), QAD_TopLabel_Popup_ID, topItem ); } @@ -2438,7 +2475,7 @@ bool SMESHGUI::CustomPopup(QAD_Desktop* parent, QPopupMenu* popup, const QString int topItem = popup->indexOf( QAD_TopLabel_Popup_ID ); if ( topItem >= 0 ) { // set bold font for popup menu's TopLabel item - QFont fnt = QApplication::font(); fnt.setBold( TRUE ); + QFont fnt = popup->font(); fnt.setBold( TRUE ); popup->removeItem( QAD_TopLabel_Popup_ID ); popup->insertItem( new CustomItem( QString("%1 ").arg( nbSel ) + type + "(s) ", fnt ), QAD_TopLabel_Popup_ID, topItem ); } diff --git a/src/SMESHGUI/SMESHGUI_EditHypothesesDlg.cxx b/src/SMESHGUI/SMESHGUI_EditHypothesesDlg.cxx index d6f2e1494..2d162996a 100644 --- a/src/SMESHGUI/SMESHGUI_EditHypothesesDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_EditHypothesesDlg.cxx @@ -745,7 +745,8 @@ void SMESHGUI_EditHypothesesDlg::InitGeom() SALOMEDS::GenericAttribute_var anAttr; SALOMEDS::AttributeName_var aName; if ( !myGeomShape->_is_nil() && (!myMesh->_is_nil() || !mySubMesh->_is_nil()) ) { - SALOMEDS::SObject_var aSO = SMESH::GetActiveStudyDocument()->FindObjectIOR( myGeomShape->GetName() ); + SALOMEDS::Study_var aStudy = SMESH::GetActiveStudyDocument(); + SALOMEDS::SObject_var aSO = aStudy->FindObjectIOR( aStudy->ConvertObjectToIOR(myGeomShape) ); if ( !aSO->_is_nil() ) { if (aSO->FindAttribute(anAttr, "AttributeName") ) { aName = SALOMEDS::AttributeName::_narrow(anAttr); diff --git a/src/SMESHGUI/SMESHGUI_MeshInfosDlg.cxx b/src/SMESHGUI/SMESHGUI_MeshInfosDlg.cxx index 40837ecde..dd130b2fe 100644 --- a/src/SMESHGUI/SMESHGUI_MeshInfosDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_MeshInfosDlg.cxx @@ -347,6 +347,8 @@ SMESHGUI_MeshInfosDlg::SMESHGUI_MeshInfosDlg( QWidget* parent, const char* name this->move( x, y ); this->show(); + cout<<"----"<height()<width()<firstIObject() ); if(myMesh->_is_nil()) return; + myActor = SMESH::FindActorByObject(myMesh); + if (!myActor) + myActor = SMESH::FindActorByEntry(IO->getEntry()); if (!myActor) return; diff --git a/src/SMESHGUI/SMESHGUI_StandardMeshInfosDlg.cxx b/src/SMESHGUI/SMESHGUI_StandardMeshInfosDlg.cxx new file mode 100644 index 000000000..37dfbdfed --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_StandardMeshInfosDlg.cxx @@ -0,0 +1,448 @@ +// SMESH SMESHGUI : GUI for SMESH component +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESHGUI_StandardMeshInfosDlg.cxx +// Author : Michael ZORIN +// Module : SMESH +// $Header$ + +// QT Includes +#include +#include +#include +#include +#include +#include +#include + +#include "QAD_Application.h" +#include "QAD_Desktop.h" +#include "QAD_WaitCursor.h" + +#include "SMESHGUI_StandardMeshInfosDlg.h" +#include "SMESHGUI_Utils.h" +#include "SMESHGUI_MeshUtils.h" +#include "SMESHGUI.h" + +#include "SMESH.hxx" + +// IDL Headers +#include "SALOMEconfig.h" +#include CORBA_SERVER_HEADER(SMESH_Mesh) +#include CORBA_SERVER_HEADER(SMESH_Group) +#include CORBA_SERVER_HEADER(GEOM_Gen) + +#include "utilities.h" + +using namespace std; + + +//================================================================================= +/*! + * SMESHGUI_StandardMeshInfosDlg::SMESHGUI_StandardMeshInfosDlg + * + * Constructor + */ +//================================================================================= +SMESHGUI_StandardMeshInfosDlg::SMESHGUI_StandardMeshInfosDlg( QWidget* parent, const char* name, bool modal, WFlags fl ) + : QDialog( parent, name, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose ) +{ + if ( !name ) + setName( "SMESHGUI_StandardMeshInfosDlg" ); + setCaption( tr( "SMESH_STANDARD_MESHINFO_TITLE" ) ); + setSizeGripEnabled( TRUE ); + + myStartSelection = true; + myIsActiveWindow = true; + + // dialog layout + QGridLayout* aDlgLayout = new QGridLayout( this ); + aDlgLayout->setSpacing( 6 ); + aDlgLayout->setMargin( 11 ); + + // mesh group box + myMeshGroup = new QGroupBox( this, "myMeshGroup" ); + myMeshGroup->setTitle( tr( "SMESH_MESH" ) ); + myMeshGroup->setColumnLayout(0, Qt::Vertical ); + myMeshGroup->layout()->setSpacing( 0 ); + myMeshGroup->layout()->setMargin( 0 ); + QGridLayout* myMeshGroupLayout = new QGridLayout( myMeshGroup->layout() ); + myMeshGroupLayout->setAlignment( Qt::AlignTop ); + myMeshGroupLayout->setSpacing( 6 ); + myMeshGroupLayout->setMargin( 11 ); + + // select button, label and line edit with mesh name + myNameLab = new QLabel( myMeshGroup, "myNameLab" ); + myNameLab->setText( tr( "SMESH_NAME" ) ); + myMeshGroupLayout->addWidget( myNameLab, 0, 0 ); + + QPixmap image0( QAD_Desktop::getResourceManager()->loadPixmap( "SMESH",tr( "ICON_SELECT" ) ) ); + mySelectBtn = new QPushButton( myMeshGroup, "mySelectBtn" ); + mySelectBtn->setPixmap( image0 ); + mySelectBtn->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) ); + myMeshGroupLayout->addWidget( mySelectBtn, 0, 1 ); + + myMeshLine = new QLineEdit( myMeshGroup, "myMeshLine" ); + myMeshGroupLayout->addWidget( myMeshLine, 0, 2 ); + + aDlgLayout->addWidget( myMeshGroup, 0, 0 ); + + // information group box + myInfoGroup = new QGroupBox( this, "myInfoGroup" ); + myInfoGroup->setTitle( tr( "SMESH_INFORMATION" ) ); + myInfoGroup->setColumnLayout(0, Qt::Vertical ); + myInfoGroup->layout()->setSpacing( 0 ); + myInfoGroup->layout()->setMargin( 0 ); + QGridLayout* myInfoGroupLayout = new QGridLayout( myInfoGroup->layout() ); + myInfoGroupLayout->setAlignment( Qt::AlignTop ); + myInfoGroupLayout->setSpacing( 6 ); + myInfoGroupLayout->setMargin( 11 ); + + // information text browser + myInfo = new QTextBrowser(myInfoGroup, "myInfo"); + myInfoGroupLayout->addWidget( myInfo, 0, 0 ); + + aDlgLayout->addWidget( myInfoGroup, 1, 0 ); + + // buttons group + myButtonsGroup = new QGroupBox( this, "myButtonsGroup" ); + myButtonsGroup->setColumnLayout(0, Qt::Vertical ); + myButtonsGroup->layout()->setSpacing( 0 ); myButtonsGroup->layout()->setMargin( 0 ); + QHBoxLayout* myButtonsGroupLayout = new QHBoxLayout( myButtonsGroup->layout() ); + myButtonsGroupLayout->setAlignment( Qt::AlignTop ); + myButtonsGroupLayout->setSpacing( 6 ); myButtonsGroupLayout->setMargin( 11 ); + + // buttons --> OK button + myOkBtn = new QPushButton( tr( "SMESH_BUT_OK" ), myButtonsGroup, "myOkBtn" ); + myOkBtn->setAutoDefault( TRUE ); myOkBtn->setDefault( TRUE ); + myButtonsGroupLayout->addStretch(); + myButtonsGroupLayout->addWidget( myOkBtn ); + myButtonsGroupLayout->addStretch(); + + aDlgLayout->addWidget( myButtonsGroup, 2, 0 ); + + mySelection = SALOME_Selection::Selection( SMESHGUI::GetSMESHGUI()->GetActiveStudy()->getSelection() ); + SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this ) ; + + // connect signals + connect( myOkBtn, SIGNAL( clicked() ), this, SLOT( close() ) ); + connect( mySelectBtn, SIGNAL( clicked() ), this, SLOT( onStartSelection() ) ); + connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( close() ) ) ; + connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( DeactivateActiveDialog() ) ) ; + connect( mySelection, SIGNAL( currentSelectionChanged() ), this, SLOT( onSelectionChanged() ) ); + + // resize and move dialog, then show + this->setMinimumSize(270, 428); + int x, y; + SMESHGUI::GetSMESHGUI()->DefineDlgPosition( this, x, y ); + this->move( x, y ); + this->show(); + + // init dialog with current selection + myMeshFilter = new SMESH_TypeFilter( MESH ); + mySelection->AddFilter( myMeshFilter ); + onSelectionChanged(); +} + +//================================================================================= +/*! + * SMESHGUI_StandardMeshInfosDlg::~SMESHGUI_StandardMeshInfosDlg + * + * Destructor + */ +//================================================================================= +SMESHGUI_StandardMeshInfosDlg::~SMESHGUI_StandardMeshInfosDlg() +{ +} + +//================================================================================= +/*! + * SMESHGUI_StandardMeshInfosDlg::DumpMeshInfos + */ +//================================================================================= +void SMESHGUI_StandardMeshInfosDlg::DumpMeshInfos() +{ + QAD_WaitCursor wc; + int nbSel = mySelection->IObjectCount(); + myInfo->clear(); + if ( nbSel == 1 ) { + myStartSelection = false; + myMeshLine->setText( "" ); + SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO( mySelection->firstIObject() ); + + if ( !aMesh->_is_nil() ) { + QString aName, anInfo; + SMESH::GetNameOfSelectedIObjects(mySelection, aName); + myMeshLine->setText( aName ); + int aNbNodes = (int)aMesh->NbNodes(); + int aNbEdges = (int)aMesh->NbEdges(); + int aNbFaces = (int)aMesh->NbFaces(); + int aNbVolumes = (int)aMesh->NbVolumes(); + + int aDimension = 0; + double aNbDimElements = 0; + if (aNbVolumes > 0) { + aNbDimElements = aNbVolumes; + aDimension = 3; + } + else if(aNbFaces > 0 ) { + aNbDimElements = aNbFaces; + aDimension = 2; + } + else if(aNbEdges > 0 ) { + aNbDimElements = aNbEdges; + aDimension = 1; + } + else if(aNbNodes > 0 ) { + aNbDimElements = aNbNodes; + aDimension = 0; + } + + // information about the mesh + anInfo.append(QString("Nb of element of dimension %1: %2
").arg(aDimension).arg(aNbDimElements)); + anInfo.append(QString("Nb of nodes: %1

").arg(aNbNodes)); + + // information about the groups of the mesh + SALOMEDS::Study_var aStudy = SMESH::GetActiveStudyDocument(); + SALOMEDS::SObject_var aMeshSO = aStudy->FindObjectIOR( aStudy->ConvertObjectToIOR(aMesh) ); + SALOMEDS::SObject_var anObj; + + bool hasGroup = false; + + // info about groups on nodes + aMeshSO->FindSubObject(Tag_NodeGroups , anObj); + if ( !anObj->_is_nil() ) + { + SALOMEDS::ChildIterator_var it = aStudy->NewChildIterator(anObj); + if (it->More()) + { + anInfo.append(QString("Groups:

")); + hasGroup = true; + } + for(; it->More(); it->Next()){ + SALOMEDS::SObject_var subObj = it->Value(); + SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( subObj->GetObject() ); + if ( !aGroup->_is_nil() ) + { + anInfo.append(QString("- %1
").arg(aGroup->GetName())); + anInfo.append(QString("%1
").arg("on nodes")); + anInfo.append(QString("%1
").arg(aGroup->Size())); + // check if the group based on geometry + SMESH::SMESH_GroupOnGeom_var aGroupOnGeom = SMESH::SMESH_GroupOnGeom::_narrow(aGroup); + if ( !aGroupOnGeom->_is_nil() ) + { + GEOM::GEOM_Object_var aGroupMainShape = aGroupOnGeom->GetShape(); + QString aShapeName = ""; + SALOMEDS::SObject_var aGeomObj, aRef; + if ( subObj->FindSubObject( 1, aGeomObj ) && aGeomObj->ReferencedObject( aRef )) + aShapeName = aRef->GetName(); + anInfo.append(QString("based on %1 geometry object

").arg(aShapeName)); + } + else + anInfo.append(QString("
")); + } + } + } + + // info about groups on edges + anObj = SALOMEDS::SObject::_nil(); + aMeshSO->FindSubObject(Tag_EdgeGroups , anObj); + if ( !anObj->_is_nil() ) + { + SALOMEDS::ChildIterator_var it = aStudy->NewChildIterator(anObj); + if (!hasGroup && it->More()) + { + anInfo.append(QString("Groups:

")); + hasGroup = true; + } + for(; it->More(); it->Next()){ + SALOMEDS::SObject_var subObj = it->Value(); + SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( subObj->GetObject() ); + if ( !aGroup->_is_nil() ) + { + anInfo.append(QString("- %1
").arg(aGroup->GetName())); + anInfo.append(QString("%1
").arg("on edges")); + anInfo.append(QString("%1
").arg(aGroup->Size())); + // check if the group based on geometry + SMESH::SMESH_GroupOnGeom_var aGroupOnGeom = SMESH::SMESH_GroupOnGeom::_narrow(aGroup); + if ( !aGroupOnGeom->_is_nil() ) + { + GEOM::GEOM_Object_var aGroupMainShape = aGroupOnGeom->GetShape(); + QString aShapeName = ""; + SALOMEDS::SObject_var aGeomObj, aRef; + if ( subObj->FindSubObject( 1, aGeomObj ) && aGeomObj->ReferencedObject( aRef )) + aShapeName = aRef->GetName(); + anInfo.append(QString("based on %1 geometry object

").arg(aShapeName)); + } + else + anInfo.append(QString("
")); + } + } + } + + // info about groups on faces + anObj = SALOMEDS::SObject::_nil(); + aMeshSO->FindSubObject(Tag_FaceGroups , anObj); + if ( !anObj->_is_nil() ) + { + SALOMEDS::ChildIterator_var it = aStudy->NewChildIterator(anObj); + if (!hasGroup && it->More()) + { + anInfo.append(QString("Groups:

")); + hasGroup = true; + } + for(; it->More(); it->Next()){ + SALOMEDS::SObject_var subObj = it->Value(); + SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( subObj->GetObject() ); + if ( !aGroup->_is_nil() ) + { + anInfo.append(QString("- %1
").arg(aGroup->GetName())); + anInfo.append(QString("%1
").arg("on faces")); + anInfo.append(QString("%1
").arg(aGroup->Size())); + // check if the group based on geometry + SMESH::SMESH_GroupOnGeom_var aGroupOnGeom = SMESH::SMESH_GroupOnGeom::_narrow(aGroup); + if ( !aGroupOnGeom->_is_nil() ) + { + GEOM::GEOM_Object_var aGroupMainShape = aGroupOnGeom->GetShape(); + QString aShapeName = ""; + SALOMEDS::SObject_var aGeomObj, aRef; + if ( subObj->FindSubObject( 1, aGeomObj ) && aGeomObj->ReferencedObject( aRef )) + aShapeName = aRef->GetName(); + anInfo.append(QString("based on %1 geometry object

").arg(aShapeName)); + } + else + anInfo.append(QString("
")); + } + } + } + + // info about groups on volumes + anObj = SALOMEDS::SObject::_nil(); + aMeshSO->FindSubObject(Tag_VolumeGroups , anObj); + if ( !anObj->_is_nil() ) + { + SALOMEDS::ChildIterator_var it = aStudy->NewChildIterator(anObj); + if (!hasGroup && it->More()) + anInfo.append(QString("Groups:
")); + for(; it->More(); it->Next()){ + SALOMEDS::SObject_var subObj = it->Value(); + SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( subObj->GetObject() ); + if ( !aGroup->_is_nil() ) + { + anInfo.append(QString("- %1
").arg(aGroup->GetName())); + anInfo.append(QString("%1
").arg("on volumes")); + anInfo.append(QString("%1
").arg(aGroup->Size())); + // check if the group based on geometry + SMESH::SMESH_GroupOnGeom_var aGroupOnGeom = SMESH::SMESH_GroupOnGeom::_narrow(aGroup); + if ( !aGroupOnGeom->_is_nil() ) + { + GEOM::GEOM_Object_var aGroupMainShape = aGroupOnGeom->GetShape(); + QString aShapeName = ""; + SALOMEDS::SObject_var aGeomObj, aRef; + if ( subObj->FindSubObject( 1, aGeomObj ) && aGeomObj->ReferencedObject( aRef )) + aShapeName = aRef->GetName(); + anInfo.append(QString("based on %1 geometry object

").arg(aShapeName)); + } + else + anInfo.append(QString("
")); + } + } + } + + myInfo->setText(anInfo); + return; + } + } + + return; +} + +//================================================================================= +// function : SelectionIntoArgument() +// purpose : Called when selection has changed +//================================================================================= +void SMESHGUI_StandardMeshInfosDlg::onSelectionChanged() +{ + if ( myStartSelection ) + DumpMeshInfos(); +} + + +//================================================================================= +// function : closeEvent() +// purpose : +//================================================================================= +void SMESHGUI_StandardMeshInfosDlg::closeEvent( QCloseEvent* e ) +{ + mySelection->ClearFilters(); + SMESHGUI::GetSMESHGUI()->ResetState(); + QDialog::closeEvent( e ); +} + + +//================================================================================= +// function : windowActivationChange() +// purpose : called when window is activated/deactivated +//================================================================================= +void SMESHGUI_StandardMeshInfosDlg::windowActivationChange( bool oldActive ) +{ + QDialog::windowActivationChange( oldActive ); + if ( isActiveWindow() && myIsActiveWindow != isActiveWindow() ) + ActivateThisDialog() ; + myIsActiveWindow = isActiveWindow(); +} + + +//================================================================================= +// function : DeactivateActiveDialog() +// purpose : +//================================================================================= +void SMESHGUI_StandardMeshInfosDlg::DeactivateActiveDialog() +{ + disconnect( mySelection, 0, this, 0 ); +} + + +//================================================================================= +// function : ActivateThisDialog() +// purpose : +//================================================================================= +void SMESHGUI_StandardMeshInfosDlg::ActivateThisDialog() +{ + /* Emit a signal to deactivate any active dialog */ + SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog() ; + connect( mySelection, SIGNAL( currentSelectionChanged() ), this, SLOT( onSelectionChanged() ) ); +} + +//================================================================================= +// function : onStartSelection() +// purpose : starts selection +//================================================================================= +void SMESHGUI_StandardMeshInfosDlg::onStartSelection() +{ + myStartSelection = true; + mySelection->AddFilter( myMeshFilter ) ; + myMeshLine->setText( tr( "Select a mesh" ) ); + onSelectionChanged(); + myStartSelection = true; +} diff --git a/src/SMESHGUI/SMESHGUI_StandardMeshInfosDlg.h b/src/SMESHGUI/SMESHGUI_StandardMeshInfosDlg.h new file mode 100644 index 000000000..04abee92a --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_StandardMeshInfosDlg.h @@ -0,0 +1,83 @@ +// SMESH SMESHGUI : GUI for SMESH component +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESHGUI_StandardMeshInfosDlg.h +// Author : Michael ZORIN +// Module : SMESH +// $Header: + +#ifndef SMESHGUI_STANDARDMESHINFOSDLG_H +#define SMESHGUI_STANDARDMESHINFOSDLG_H + +#include "SMESH_TypeFilter.hxx" + +// QT Includes +#include + +class QGroupBox; +class QLabel; +class QPushButton; +class QLineEdit; +class QTextBrowser; +class SALOME_Selection; + +class SMESHGUI_StandardMeshInfosDlg : public QDialog +{ + Q_OBJECT + +public: + SMESHGUI_StandardMeshInfosDlg( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~SMESHGUI_StandardMeshInfosDlg(); + +protected: + void closeEvent( QCloseEvent* e ); + void windowActivationChange( bool oldActive ); + void DumpMeshInfos(); + +private slots: + void onSelectionChanged(); + void DeactivateActiveDialog() ; + void ActivateThisDialog(); + void onStartSelection(); + +private: + SALOME_Selection* mySelection; + bool myStartSelection; + bool myIsActiveWindow; + + Handle(SMESH_TypeFilter) myMeshFilter; + + QLabel* myNameLab; + QPushButton* mySelectBtn; + QLineEdit* myMeshLine; + + QTextBrowser* myInfo; + + QGroupBox* myMeshGroup; + QGroupBox* myInfoGroup; + + QGroupBox* myButtonsGroup; + QPushButton* myOkBtn; +}; + +#endif // SMESHGUI_STANDARDMESHINFOSDLG_H diff --git a/src/SMESHGUI/SMESHGUI_SymmetryDlg.cxx b/src/SMESHGUI/SMESHGUI_SymmetryDlg.cxx index d073f812f..31a92ef23 100644 --- a/src/SMESHGUI/SMESHGUI_SymmetryDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_SymmetryDlg.cxx @@ -592,7 +592,10 @@ void SMESHGUI_SymmetryDlg::SelectionIntoArgument() myMesh = SMESH::GetMeshByIO( mySelection->firstIObject() ); if(myMesh->_is_nil()) return; + myActor = SMESH::FindActorByObject(myMesh); + if (!myActor) + myActor = SMESH::FindActorByEntry(IO->getEntry()); if (!myActor) return; diff --git a/src/SMESHGUI/SMESHGUI_TranslationDlg.cxx b/src/SMESHGUI/SMESHGUI_TranslationDlg.cxx index de761dd5f..641ec5c7b 100644 --- a/src/SMESHGUI/SMESHGUI_TranslationDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_TranslationDlg.cxx @@ -560,7 +560,10 @@ void SMESHGUI_TranslationDlg::SelectionIntoArgument() myMesh = SMESH::GetMeshByIO(IO); if(myMesh->_is_nil()) return; + myActor = SMESH::FindActorByObject(myMesh); + if (!myActor) + myActor = SMESH::FindActorByEntry(IO->getEntry()); if (!myActor) return; diff --git a/src/SMESHGUI/SMESH_msg_en.po b/src/SMESHGUI/SMESH_msg_en.po index c1187f34d..8a0a4163b 100644 --- a/src/SMESHGUI/SMESH_msg_en.po +++ b/src/SMESHGUI/SMESH_msg_en.po @@ -722,6 +722,10 @@ msgstr "Rotation" msgid "SMESH_MESHINFO_TITLE" msgstr "Mesh Infos" +#Standard Mesh Infos +msgid "SMESH_STANDARD_MESHINFO_TITLE" +msgstr "Standard Mesh Infos" + #Mesh Infos msgid "SMESH_MESHINFO_NAME" msgstr "Name" @@ -790,6 +794,10 @@ msgstr "Heterogenous" msgid "SMESH_BAD_SELECTION" msgstr "No valid selection" +#Information : +msgid "SMESH_INFORMATION" +msgstr "Information" + # --------- Create hypotheses/algorithms --------- msgid "SMESH_CREATE_HYPOTHESES" @@ -1665,8 +1673,8 @@ msgstr "Number of digits after point" msgid "SMESHGUI_PrecisionDlg::NOT_USE" msgstr "Do not use" - - +msgid "NON_SMESH_OBJECTS_SELECTED" +msgstr "There are objects selected which do not belong to %1 component." diff --git a/src/SMESH_I/Makefile.in b/src/SMESH_I/Makefile.in index a2b64c5da..2517d100f 100644 --- a/src/SMESH_I/Makefile.in +++ b/src/SMESH_I/Makefile.in @@ -44,7 +44,8 @@ EXPORT_HEADERS= \ SMESH_3D_Algo_i.hxx \ SMESH_subMesh_i.hxx \ SMESH_Mesh_i.hxx \ - SMESH_Hypothesis_i.hxx + SMESH_Hypothesis_i.hxx \ + SMESH.hxx EXPORT_PYSCRIPTS = smeshpy.py SMESH_test.py diff --git a/src/SMESH_I/SMESH.hxx b/src/SMESH_I/SMESH.hxx new file mode 100644 index 000000000..ea68b0445 --- /dev/null +++ b/src/SMESH_I/SMESH.hxx @@ -0,0 +1,56 @@ +// SMESH SMESH_I : +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : SMESH.hxx +// Author : Michael ZORIN +// Module : SMESH +// $Header: + +#ifndef _SMESH_SMESH_HXX_ +#define _SMESH_SMESH_HXX_ + +// Tags definition +enum { + // Top level + Tag_HypothesisRoot = 1, // hypotheses root + Tag_AlgorithmsRoot = 2, // algorithms root + // Mesh/Submesh + Tag_RefOnShape = 1, // references to shape + Tag_RefOnAppliedHypothesis = 2, // applied hypotheses root + Tag_RefOnAppliedAlgorithms = 3, // applied algorithms root + // Mesh only + Tag_SubMeshOnVertex = 4, // sub-meshes roots by type + Tag_SubMeshOnEdge = 5, // ... + Tag_SubMeshOnWire = 6, // ... + Tag_SubMeshOnFace = 7, // ... + Tag_SubMeshOnShell = 8, // ... + Tag_SubMeshOnSolid = 9, // ... + Tag_SubMeshOnCompound = 10, // ... + Tag_NodeGroups = 11, // Group roots by type + Tag_EdgeGroups = 12, // ... + Tag_FaceGroups = 13, // ... + Tag_VolumeGroups = 14 // ... +}; + +#endif + diff --git a/src/SMESH_I/SMESH_Gen_i_1.cxx b/src/SMESH_I/SMESH_Gen_i_1.cxx index dd9c3893f..4e50171a6 100644 --- a/src/SMESH_I/SMESH_Gen_i_1.cxx +++ b/src/SMESH_I/SMESH_Gen_i_1.cxx @@ -33,6 +33,8 @@ #include "SMESH_Algo_i.hxx" #include "SMESH_Group_i.hxx" +#include "SMESH.hxx" + #include CORBA_CLIENT_HEADER(SALOME_ModuleCatalog) #include "utilities.h" @@ -46,28 +48,6 @@ static int MYDEBUG = 0; static int MYDEBUG = 0; #endif -// Tags definition =========================================================== -// Top level -long Tag_HypothesisRoot = 1; // hypotheses root -long Tag_AlgorithmsRoot = 2; // algorithms root -// Mesh/Submesh -long Tag_RefOnShape = 1; // references to shape -long Tag_RefOnAppliedHypothesis = 2; // applied hypotheses root -long Tag_RefOnAppliedAlgorithms = 3; // applied algorithms root -// Mesh only -long Tag_SubMeshOnVertex = 4; // sub-meshes roots by type -long Tag_SubMeshOnEdge = 5; // ... -long Tag_SubMeshOnWire = 6; // ... -long Tag_SubMeshOnFace = 7; // ... -long Tag_SubMeshOnShell = 8; // ... -long Tag_SubMeshOnSolid = 9; // ... -long Tag_SubMeshOnCompound = 10; // ... -long Tag_NodeGroups = 11; // Group roots by type -long Tag_EdgeGroups = 12; // ... -long Tag_FaceGroups = 13; // ... -long Tag_VolumeGroups = 14; // ... -// =========================================================================== - //============================================================================= /*! * Get...Tag [ static ] diff --git a/src/SMESH_I/SMESH_MEDFamily_i.hxx b/src/SMESH_I/SMESH_MEDFamily_i.hxx index a5a8a52df..e48a49626 100644 --- a/src/SMESH_I/SMESH_MEDFamily_i.hxx +++ b/src/SMESH_I/SMESH_MEDFamily_i.hxx @@ -57,13 +57,13 @@ public : SMESH_MEDFamily_i(int identifier, SMESH_subMesh_i* sm, string name, string description, SALOME_MED::medEntityMesh entity ); SMESH_MEDFamily_i(const SMESH_MEDFamily_i & f); - - // IDL Methods - void setProtocol(SALOME::TypeOfCommunication typ) {} - void release() {} - SALOME::Sender_ptr getSenderForNumber(long int) {return SALOME::Sender::_nil();} - SALOME::Sender_ptr getSenderForNumberIndex() {return SALOME::Sender::_nil();} - + + // IDL Methods + void setProtocol(SALOME::TypeOfCommunication typ) {} + void release() {} + SALOME::Sender_ptr getSenderForNumber(long int) {return SALOME::Sender::_nil();} + SALOME::Sender_ptr getSenderForNumberIndex() {return SALOME::Sender::_nil();} + CORBA::Long getIdentifier() throw (SALOME::SALOME_Exception); CORBA::Long getNumberOfAttributes() diff --git a/src/SMESH_I/SMESH_MEDMesh_i.hxx b/src/SMESH_I/SMESH_MEDMesh_i.hxx index 1c9308e1d..e8e82f17b 100644 --- a/src/SMESH_I/SMESH_MEDMesh_i.hxx +++ b/src/SMESH_I/SMESH_MEDMesh_i.hxx @@ -74,12 +74,12 @@ class SMESH_MEDMesh_i: SMESH_MEDMesh_i(SMESH_Mesh_i * m); ~SMESH_MEDMesh_i(); - // IDL Methods + // IDL Methods void setProtocol(SALOME::TypeOfCommunication typ) {} void release() {} SALOME::Sender_ptr getSenderForCoordinates(long int) {return SALOME::Sender::_nil();} SALOME::Sender_ptr getSenderForConnectivity(long int, long int, long int, long int) {return SALOME::Sender::_nil();} - + char *getName() throw(SALOME::SALOME_Exception); CORBA::Long getSpaceDimension() throw(SALOME::SALOME_Exception); diff --git a/src/SMESH_I/SMESH_MeshEditor_i.cxx b/src/SMESH_I/SMESH_MeshEditor_i.cxx index 8cdfa30f3..c18cd7dc9 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.cxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.cxx @@ -252,7 +252,7 @@ CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfEleme CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject) { SMESH::long_array_var anElementsId = theObject->GetIDs(); - Reorient(anElementsId); + return Reorient(anElementsId); } //============================================================================= @@ -298,7 +298,7 @@ CORBA::Boolean CORBA::Double MaxAngle) { SMESH::long_array_var anElementsId = theObject->GetIDs(); - TriToQuad(anElementsId, Criterion, MaxAngle); + return TriToQuad(anElementsId, Criterion, MaxAngle); } //============================================================================= @@ -365,7 +365,7 @@ CORBA::Boolean CORBA::Boolean Diag13) { SMESH::long_array_var anElementsId = theObject->GetIDs(); - SplitQuad(anElementsId, Diag13); + return SplitQuad(anElementsId, Diag13); } //============================================================================= diff --git a/src/SMESH_SWIG/Makefile.in b/src/SMESH_SWIG/Makefile.in index bf8573669..c6c8c0403 100644 --- a/src/SMESH_SWIG/Makefile.in +++ b/src/SMESH_SWIG/Makefile.in @@ -74,6 +74,12 @@ EXPORT_PYSCRIPTS = libSMESH_Swig.py \ SMESH_controls.py \ SMESH_freebord.py \ SMESH_blocks.py \ + SMESH_BelongToGeom.py \ + SMESH_GroupFromGeom2.py \ + SMESH_box.py \ + SMESH_demo_hexa2_upd.py \ + SMESH_hexaedre.py \ + SMESH_Sphere.py \ SMESH_GroupFromGeom.py LIB_CLIENT_IDL = SALOMEDS.idl \ diff --git a/src/SMESH_SWIG/SMESH_GroupFromGeom2.py b/src/SMESH_SWIG/SMESH_GroupFromGeom2.py new file mode 100755 index 000000000..37f333d88 --- /dev/null +++ b/src/SMESH_SWIG/SMESH_GroupFromGeom2.py @@ -0,0 +1,53 @@ +#============================================================================== +# Info. +# Bug (from script, bug) : SMESH_GroupFromGeom.py, PAL6945 +# Modified : 25/11/2004 +# Author : Kovaltchuk Alexey +# Project : PAL/SALOME +#============================================================================== +from SMESH_test1 import * +import SMESH + +# Compute the mesh created in SMESH_test1 + +smesh.Compute(mesh, box) + +# Create geometry groups on plane: +aGeomGroup1 = geompy.CreateGroup(face , geompy.ShapeType["FACE"]) +geompy.AddObject(aGeomGroup1, 1) + +aGeomGroup2 = geompy.CreateGroup(face , geompy.ShapeType["EDGE"]) + +geompy.AddObject(aGeomGroup2, 3) +geompy.AddObject(aGeomGroup2, 6) +geompy.AddObject(aGeomGroup2, 8) +geompy.AddObject(aGeomGroup2, 10) + +geompy.addToStudy(aGeomGroup1, "Group on Faces") +geompy.addToStudy(aGeomGroup2, "Group on Edges") + +aSmeshGroup1 = mesh.CreateGroupFromGEOM(SMESH.FACE, "SMESHGroup1", aGeomGroup1) +aSmeshGroup2 = mesh.CreateGroupFromGEOM(SMESH.EDGE, "SMESHGroup2", aGeomGroup2) + +print "Create aGroupOnShell - a group linked to a shell" +aGroupOnShell = mesh.CreateGroupFromGEOM(SMESH.EDGE, "GroupOnShell", shell) +print "aGroupOnShell type =", aGroupOnShell.GetType() +print "aGroupOnShell size =", aGroupOnShell.Size() +print "aGroupOnShell ids :", aGroupOnShell.GetListOfID() + +print " " + +print "Modify hypothesis: 100 -> 50" +hypLen1.SetLength(50) +print "Contents of aGroupOnShell changes:" +print "aGroupOnShell size =", aGroupOnShell.Size() +print "aGroupOnShell ids :", aGroupOnShell.GetListOfID() + +print " " + +print "Re-compute mesh, contents of aGroupOnShell changes again:" +smesh.Compute(mesh, box) +print "aGroupOnShell size =", aGroupOnShell.Size() +print "aGroupOnShell ids :", aGroupOnShell.GetListOfID() + +salome.sg.updateObjBrowser(1); diff --git a/src/SMESH_SWIG/SMESH_Sphere.py b/src/SMESH_SWIG/SMESH_Sphere.py new file mode 100644 index 000000000..9c6bc42a0 --- /dev/null +++ b/src/SMESH_SWIG/SMESH_Sphere.py @@ -0,0 +1,107 @@ +# GEOM GEOM_SWIG : binding of C++ omplementaion with Python +# +# Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +# +# +# +# File : GEOM_Sphere.py +# Author : Damien COQUERET, Open CASCADE +# Module : GEOM +# $Header: + +from geompy import * +from math import * + +from meshpy import * + +# It is an example of creating a hexahedrical mesh on a sphere. +# +# Used approach allows to avoid problems with degenerated and +# seam edges without special processing of geometrical shapes + +#----------------------------------------------------------------------- +#Variables +Radius = 100. +Dist = Radius / 2. +Factor = 2.5 +Angle90 = pi / 2. +NbSeg = 10 + +PointsList = [] +ShapesList = [] + +#Basic Elements +P0 = MakeVertex(0., 0., 0.) +P1 = MakeVertex(-Dist, -Dist, -Dist) +P2 = MakeVertex(-Dist, -Dist, Dist) +P3 = MakeVertex(-Dist, Dist, Dist) +P4 = MakeVertex(-Dist, Dist, -Dist) + +VZ = MakeVectorDXDYDZ(0., 0., 1.) + +#Construction Elements +PointsList.append(P1) +PointsList.append(P2) +PointsList.append(P3) +PointsList.append(P4) +PointsList.append(P1) + +PolyLine = MakePolyline(PointsList) + +Face1 = MakeFace(PolyLine, 1) +Face2 = MakeScaleTransform(Face1, P0, Factor) +Face3 = MakeScaleTransform(Face1, P0, -1.) + +#Models +Sphere = MakeSphereR(Radius) + +Block = MakeHexa2Faces(Face1, Face2) +Cube = MakeHexa2Faces(Face1, Face3) + +Common1 = MakeBoolean(Sphere, Block, 1) +Common2 = MakeRotation(Common1, VZ, Angle90) + +MultiBlock1 = MakeMultiTransformation1D(Common1, 21, -1, 3) +MultiBlock2 = MakeMultiTransformation1D(Common2, 31, -1, 3) + +#Reconstruct sphere from several blocks +ShapesList.append(Cube) +ShapesList.append(MultiBlock1) +ShapesList.append(MultiBlock2) +Compound = MakeCompound(ShapesList) + +Result = MakeGlueFaces(Compound, 0.1) + +#addToStudy +Id_Sphere = addToStudy(Sphere, "Sphere") +Id_Cube = addToStudy(Cube, "Cube") + +Id_Common1 = addToStudy(Common1, "Common1") +Id_Common2 = addToStudy(Common2, "Common2") + +Id_MultiBlock1 = addToStudy(MultiBlock1, "MultiBlock1") +Id_MultiBlock2 = addToStudy(MultiBlock2, "MultiBlock2") + +Id_Result = addToStudy(Result, "Result") + +#----------------------------------------------------------------------- +#Meshing +my_hexa = MeshHexa(Result, NbSeg, "Sphere_Mesh") +my_hexa.Compute() diff --git a/src/SMESH_SWIG/SMESH_box.py b/src/SMESH_SWIG/SMESH_box.py new file mode 100755 index 000000000..2902c739b --- /dev/null +++ b/src/SMESH_SWIG/SMESH_box.py @@ -0,0 +1,73 @@ +#============================================================================== +# Info. +# Bug (from script, bug) : box.py, PAL5223 +# Modified : 25/11/2004 +# Author : Kovaltchuk Alexey +# Project : PAL/SALOME +#============================================================================== +# +# Salome geometry and meshing for a box +# +import salome +from salome import sg +import geompy + +import StdMeshers + +# ---- launch GEOM + +geom = salome.lcc.FindOrLoadComponent("FactoryServer", "GEOM") +meshgenerator = salome.lcc.FindOrLoadComponent("FactoryServer", "SMESH") + +###geom.GetCurrentStudy(salome.myStudy._get_StudyId()) +meshgenerator.SetCurrentStudy(salome.myStudy) + +# Plate + +box = geompy.MakeBox(0.,0.,0.,1.,1.,1.) +boxId = geompy.addToStudy(box,"box") + +# ---- launch SMESH + +smeshgui = salome.ImportComponentGUI("SMESH") +smeshgui.Init(salome.myStudyId) +# meshgenerator=smeshpy.smeshpy() + + +# Hypothesis + +hypL1=meshgenerator.CreateHypothesis("LocalLength","libStdMeshersEngine.so") +hypL1.SetLength(0.25) +hypL1Id = salome.ObjectToID(hypL1) +smeshgui.SetName(hypL1Id, "LocalLength") + +# Algorithm + +alg1D=meshgenerator.CreateHypothesis("Regular_1D", "libStdMeshersEngine.so") +alg1DId = salome.ObjectToID(alg1D) +smeshgui.SetName(alg1DId, "algo1D") + +alg2D=meshgenerator.CreateHypothesis("Quadrangle_2D", "libStdMeshersEngine.so") +alg2DId = salome.ObjectToID(alg2D) +smeshgui.SetName(alg2DId, "algo2D") + +alg3D=meshgenerator.CreateHypothesis("Hexa_3D", "libStdMeshersEngine.so") +alg3DId = salome.ObjectToID(alg3D) +smeshgui.SetName(alg3DId, "algo3D") + +# ---- init a Mesh + +box_mesh=meshgenerator.CreateMesh(box) +box_meshId = salome.ObjectToID(box_mesh) +smeshgui.SetName(box_meshId, "box_mesh") + +# ---- set Hypothesis & Algorithm + +box_mesh.AddHypothesis(box,alg1D) +box_mesh.AddHypothesis(box,alg2D) +box_mesh.AddHypothesis(box,alg3D) +box_mesh.AddHypothesis(box,hypL1) + +meshgenerator.Compute(box_mesh,box) + +sg.updateObjBrowser(1) diff --git a/src/SMESH_SWIG/SMESH_demo_hexa2_upd.py b/src/SMESH_SWIG/SMESH_demo_hexa2_upd.py new file mode 100755 index 000000000..755214a59 --- /dev/null +++ b/src/SMESH_SWIG/SMESH_demo_hexa2_upd.py @@ -0,0 +1,210 @@ +#============================================================================== +# Info. +# Bug (from script, bug) : SMESH_demo_hexa2_upd.py, PAL6781 +# Modified : 25/11/2004 +# Author : Kovaltchuk Alexey +# Project : PAL/SALOME +#============================================================================== +# Tetrahedrization of a geometry (box minus a inner cylinder). +# Hypothesis and algorithms for the mesh generation are not global: +# the mesh of some edges is thinner +# + +import salome +import geompy + +import StdMeshers +import NETGENPlugin + +geom = salome.lcc.FindOrLoadComponent("FactoryServer", "GEOM") +smesh = salome.lcc.FindOrLoadComponent("FactoryServer", "SMESH") + +smeshgui = salome.ImportComponentGUI("SMESH") +smeshgui.Init(salome.myStudyId); + +import math + +# ----------------------------------------------------------------------------- + +ShapeTypeShell = 3 +ShapeTypeFace = 4 +ShapeTypeEdge = 6 + +a = math.sqrt(2.)/4. +ma = - a +zero = 0. +un = 1. +mun= - un +demi = 1./2. + +Orig = geompy.MakeVertex(zero,zero,zero) +P0 = geompy.MakeVertex(a,a,zero) +P1 = geompy.MakeVertex(zero,demi,zero) +P2 = geompy.MakeVertex(ma,a,zero) +P3 = geompy.MakeVertex(mun,un,zero) +P4 = geompy.MakeVertex(un,un,zero) +P5 = geompy.MakeVertex(zero,zero,un) + +arc = geompy.MakeArc(P0,P1,P2) +e1 = geompy.MakeEdge(P2,P3) +e2 = geompy.MakeEdge(P3,P4) +e3 = geompy.MakeEdge(P4,P0) + +list = [] +list.append(arc) +list.append(e1) +list.append(e2) +list.append(e3) + +wire = geompy.MakeWire(list) +face = geompy.MakeFace(wire,1) + +dir = geompy.MakeVector(Orig,P5) +vol1 = geompy.MakePipe(face,dir) + +angle = math.pi/2. +#dir = geom.MakeVector(Orig,P5) +vol2 = geompy.MakeRotation(vol1,dir,angle) + +vol3 = geompy.MakeRotation(vol2,dir,angle) + +vol4 = geompy.MakeRotation(vol3,dir,angle) + +list = [] +list.append(vol1) +list.append(vol2) +list.append(vol3) +list.append(vol4) + +volComp = geompy.MakeCompound(list) + +tol3d = 1.e-3 +vol = geompy.MakeGlueFaces(volComp,tol3d) +idVol = geompy.addToStudy(vol,"volume") + +print "Analysis of the final volume:" +subShellList = geompy.SubShapeAllSorted(vol,ShapeTypeShell) +subFaceList = geompy.SubShapeAllSorted(vol,ShapeTypeFace) +subEdgeList = geompy.SubShapeAllSorted(vol,ShapeTypeEdge) + +print "number of Shells in the volume : ",len(subShellList) +print "number of Faces in the volume : ",len(subFaceList) +print "number of Edges in the volume : ",len(subEdgeList) + +idSubEdge = [] +for k in range(len(subEdgeList)): + idSubEdge.append(geompy.addToStudyInFather(vol,subEdgeList[k],"SubEdge"+str(k))) + +edgeZ = [] +edgeZ.append(subEdgeList[0]) +edgeZ.append(subEdgeList[3]) +edgeZ.append(subEdgeList[10]) +edgeZ.append(subEdgeList[11]) +edgeZ.append(subEdgeList[20]) +edgeZ.append(subEdgeList[21]) +edgeZ.append(subEdgeList[28]) +edgeZ.append(subEdgeList[31]) + +idEdgeZ = [] +for i in range(8): + idEdgeZ.append(geompy.addToStudyInFather(vol,edgeZ[i],"EdgeZ"+str(i+1))) + +### ---------------------------- SMESH -------------------------------------- + +# ---- create Hypothesis + +print "-------------------------- create Hypothesis" + +print "-------------------------- NumberOfSegments the global one" + +numberOfSegments = 10 + +hypNbSeg=smesh.CreateHypothesis("NumberOfSegments","libStdMeshersEngine.so") +hypNbSeg.SetNumberOfSegments(numberOfSegments) +hypNbSegID = hypNbSeg.GetId() +print hypNbSeg.GetName() +print hypNbSegID +print hypNbSeg.GetNumberOfSegments() + +smeshgui.SetName(salome.ObjectToID(hypNbSeg), "NumberOfSegments") + +print "-------------------------- NumberOfSegments in the Z direction" + +numberOfSegmentsZ = 40 + +hypNbSegZ=smesh.CreateHypothesis("NumberOfSegments","libStdMeshersEngine.so") +hypNbSegZ.SetNumberOfSegments(numberOfSegmentsZ) +hypNbSegZID = hypNbSegZ.GetId() +print hypNbSegZ.GetName() +print hypNbSegZID +print hypNbSegZ.GetNumberOfSegments() + +smeshgui.SetName(salome.ObjectToID(hypNbSegZ), "NumberOfSegmentsZ") + +# ---- create Algorithms + +print "-------------------------- create Algorithms" + +print "-------------------------- Regular_1D" + +regular1D=smesh.CreateHypothesis("Regular_1D", "libStdMeshersEngine.so") +smeshgui.SetName(salome.ObjectToID(regular1D), "Wire Discretisation") + +print "-------------------------- Quadrangle_2D" + +quad2D=smesh.CreateHypothesis("Quadrangle_2D", "libStdMeshersEngine.so") +smeshgui.SetName(salome.ObjectToID(quad2D), "Quadrangle_2D") + +print "-------------------------- Hexa_3D" + +hexa3D=smesh.CreateHypothesis("Hexa_3D", "libStdMeshersEngine.so") +smeshgui.SetName(salome.ObjectToID(hexa3D), "Hexa_3D") + +# ---- init a Mesh with the volume + +mesh = smesh.CreateMesh(vol) +smeshgui.SetName(salome.ObjectToID(mesh), "meshVolume") + +# ---- add hypothesis to the volume + +print "-------------------------- add hypothesis to the volume" + +ret=mesh.AddHypothesis(vol,regular1D) +print ret +ret=mesh.AddHypothesis(vol,hypNbSeg) +print ret +ret=mesh.AddHypothesis(vol,quad2D) +print ret +ret=mesh.AddHypothesis(vol,hexa3D) +print ret + +for i in range(8): + print "-------------------------- add hypothesis to edge in the Z directions", (i+1) + + subMeshEdgeZ = mesh.GetSubMesh(edgeZ[i],"SubMeshEdgeZ_"+str(i+1)) + + retZ = mesh.AddHypothesis(edgeZ[i],hypNbSegZ) + print " add hyp Z ", retZ + +salome.sg.updateObjBrowser(1) + +print "-------------------------- compute the mesh of the volume" + +ret=smesh.Compute(mesh,vol) + +print ret +if ret != 0: +## log=mesh.GetLog(0) # no erase trace +## for linelog in log: +## print linelog + print "Information about the MeshBox :" + print "Number of nodes : ", mesh.NbNodes() + print "Number of edges : ", mesh.NbEdges() + print "Number of faces : ", mesh.NbFaces() + print "Number of triangles : ", mesh.NbTriangles() + print "Number of volumes : ", mesh.NbVolumes() + print "Number of tetrahedrons: ", mesh.NbTetras() +else: + print "problem when Computing the mesh" + +salome.sg.updateObjBrowser(1) diff --git a/src/SMESH_SWIG/SMESH_hexaedre.py b/src/SMESH_SWIG/SMESH_hexaedre.py new file mode 100755 index 000000000..1b93e1c08 --- /dev/null +++ b/src/SMESH_SWIG/SMESH_hexaedre.py @@ -0,0 +1,148 @@ +#============================================================================== +# Info. +# Bug (from script, bug) : hexaedre_modified.py, PAL6194, PAL7153 +# Modified : 25/11/2004 +# Author : Kovaltchuk Alexey +# Project : PAL/SALOME +#============================================================================== + +import salome +from salome import sg + +import geompy + +import math + +# ----------------------------------------------------------------------------- + +geom = salome.lcc.FindOrLoadComponent("FactoryServer", "GEOM") +myBuilder = salome.myStudy.NewBuilder() +gg = salome.ImportComponentGUI("GEOM") +from salome import sg + +ShapeTypeCompSolid = 1 +ShapeTypeSolid = 2 +ShapeTypeShell = 3 +ShapeTypeFace = 4 +ShapeTypeWire = 5 +ShapeTypeEdge = 6 +ShapeTypeVertex = 7 + +Boolop_common = 1 +Boolop_cut = 2 +Boolop_fuse = 3 +Boolop_section = 4 + +p0 = geompy.MakeVertex(0., 0., 0.) +px = geompy.MakeVertex(100., 0., 0.) +py = geompy.MakeVertex(0., 100., 0.) +pz = geompy.MakeVertex(0., 0., 100.) +vx = geompy.MakeVector(p0, px) +vy = geompy.MakeVector(p0, py) +vz = geompy.MakeVector(p0, pz) + +sphereExt = geompy.MakeSphere( 0., 0., 0., 400.) +sphereInt = geompy.MakeSphere( 0.,-50., 0., 350.) +sphereA = geompy.MakeSphere( -400., 50., 50., 400.) +sphereB = geompy.MakeSphere( 350.,-50.,-50., 350.) +ptcyle = geompy.MakeVertex(0., -300., -450.) +cylindre = geompy.MakeCylinder(ptcyle,vz,500.,900.) + +vol1=geompy.MakeCut(sphereExt,sphereA) +vol2=geompy.MakeCut(vol1,sphereB) +vol3=geompy.MakeCut(vol2,cylindre) +blob=geompy.MakeCut(vol3,sphereInt) + +idblob = geompy.addToStudy(blob,"blob") + +aretes = [] +aretes = geompy.SubShapeAllSorted(blob, ShapeTypeEdge) +eid=0 + +# ------------------------------- +# --- numerotation des aretes +##for edge in aretes: +## edname="arete%d"%eid +## idedge=geompy.addToStudy(edge,edname) +## eid=eid+1 + +salome.sg.updateObjBrowser(1) + +# --- epaisseur 0 2 8 10 +# --- hauteur 1 3 9 11 +# --- largeur 4 5 6 7 + +# ----------------------------------------------------------------------------- + +print "-------------------------- mesh" + +import SMESH +import StdMeshers +smesh = salome.lcc.FindOrLoadComponent("FactoryServer", "SMESH") +smesh.SetCurrentStudy(salome.myStudy) + +# ---- create Hypothesis +print "-------------------------- create Hypothesis" +numberOfSegments = 4 +hypNbSegA=smesh.CreateHypothesis("NumberOfSegments", "libStdMeshersEngine.so") +hypNbSegA.SetNumberOfSegments(numberOfSegments) +numberOfSegments = 10 +hypNbSegB=smesh.CreateHypothesis("NumberOfSegments", "libStdMeshersEngine.so") +hypNbSegB.SetNumberOfSegments(numberOfSegments) +numberOfSegments = 15 +hypNbSegC=smesh.CreateHypothesis("NumberOfSegments", "libStdMeshersEngine.so") +hypNbSegC.SetNumberOfSegments(numberOfSegments) + +# ---- create Algorithms +print "-------------------------- create Algorithms" +regular1D=smesh.CreateHypothesis("Regular_1D", "libStdMeshersEngine.so") +quad2D=smesh.CreateHypothesis("Quadrangle_2D", "libStdMeshersEngine.so") +hexa3D=smesh.CreateHypothesis("Hexa_3D", "libStdMeshersEngine.so") + +# ---- init a Mesh with the geom shape +shape_mesh = blob +myMesh=smesh.CreateMesh(shape_mesh) + +# ---- add hypothesis and algorithms to mesh +print "-------------------------- add hypothesis to mesh" +myMesh.AddHypothesis(shape_mesh,regular1D) +myMesh.AddHypothesis(shape_mesh,quad2D) +myMesh.AddHypothesis(shape_mesh,hexa3D) + +#myMesh.AddHypothesis(shape_mesh,hypNbSeg) + +myMesh.AddHypothesis(aretes[0],hypNbSegA) +myMesh.AddHypothesis(aretes[2],hypNbSegA) +myMesh.AddHypothesis(aretes[8],hypNbSegA) +myMesh.AddHypothesis(aretes[10],hypNbSegA) + +myMesh.AddHypothesis(aretes[1],hypNbSegC) +myMesh.AddHypothesis(aretes[3],hypNbSegC) +myMesh.AddHypothesis(aretes[9],hypNbSegC) +myMesh.AddHypothesis(aretes[11],hypNbSegC) + +myMesh.AddHypothesis(aretes[4],hypNbSegB) +myMesh.AddHypothesis(aretes[5],hypNbSegB) +myMesh.AddHypothesis(aretes[6],hypNbSegB) +myMesh.AddHypothesis(aretes[7],hypNbSegB) + +# ---- compute mesh + +print "-------------------------- compute mesh" +ret=smesh.Compute(myMesh, shape_mesh) +print ret +if ret != 0: + #log=myMesh.GetLog(0) # no erase trace + #for linelog in log: + # print linelog + print "Information about the Mesh:" + print "Number of nodes : ", myMesh.NbNodes() + print "Number of edges : ", myMesh.NbEdges() + print "Number of faces : ", myMesh.NbFaces() + print "Number of quadrangles : ", myMesh.NbQuadrangles() + print "Number of volumes : ", myMesh.NbVolumes() + print "Number of hexahedrons : ", myMesh.NbHexas() +else: + print "problem when Computing the mesh" + +salome.sg.updateObjBrowser(1) diff --git a/src/SMESH_SWIG/meshpy.py b/src/SMESH_SWIG/meshpy.py index 757a6fea6..effc62d1d 100644 --- a/src/SMESH_SWIG/meshpy.py +++ b/src/SMESH_SWIG/meshpy.py @@ -10,6 +10,8 @@ import salome import StdMeshers +import SMESH + # Variables # --------- @@ -98,4 +100,27 @@ class MeshHexaImpl: smesh.Compute(self.mesh, self.piece) salome.sg.updateObjBrowser(1) + # Creates mesh group based on a geometric group + # -------------------- + + def Group(self, grp, name=""): + if name == "": + name = grp.GetName() + tgeo = geompy.GroupOp.GetType(grp) + if tgeo == geompy.ShapeType["VERTEX"]: + type = SMESH.NODE + elif tgeo == geompy.ShapeType["EDGE"]: + type = SMESH.EDGE + elif tgeo == geompy.ShapeType["FACE"]: + type = SMESH.FACE + elif tgeo == geompy.ShapeType["SOLID"]: + type = SMESH.VOLUME + return self.mesh.CreateGroupFromGEOM(type, name, grp) + + # Export mesh in a MED file + # -------------------- + + def ExportMED(self, filename, groups=1): + self.mesh.ExportMED(filename, groups) + MeshHexa = MeshHexaImpl diff --git a/src/StdMeshers/Makefile.in b/src/StdMeshers/Makefile.in index 92e94c168..caa833378 100644 --- a/src/StdMeshers/Makefile.in +++ b/src/StdMeshers/Makefile.in @@ -70,6 +70,7 @@ LIB_SRC = \ StdMeshers_Regular_1D.cxx \ StdMeshers_Quadrangle_2D.cxx \ StdMeshers_MEFISTO_2D.cxx \ + StdMeshers_Penta_3D.cxx \ StdMeshers_Hexa_3D.cxx LIB_SERVER_IDL = @@ -82,8 +83,8 @@ BIN_SRC = # additionnal information to compil and link file CPPFLAGS+= $(OCC_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome $(BOOST_CPPFLAGS) -CXXFLAGS+= $(OCC_CXXFLAGS) -I${KERNEL_ROOT_DIR}/include/salome +CXXFLAGS+= $(OCC_CXXFLAGS) -I${KERNEL_ROOT_DIR}/include/salome -I${GEOM_ROOT_DIR}/include/salome -LDFLAGS+= -lSMESHimpl -lMEFISTO2D -L${KERNEL_ROOT_DIR}/lib/salome +LDFLAGS+= -lSMESHimpl -lMEFISTO2D -L${KERNEL_ROOT_DIR}/lib/salome -L${GEOM_ROOT_DIR}/lib/salome @CONCLUDE@ diff --git a/src/StdMeshers/StdMeshers_Hexa_3D.cxx b/src/StdMeshers/StdMeshers_Hexa_3D.cxx index 580c48ee8..f80cd53cb 100644 --- a/src/StdMeshers/StdMeshers_Hexa_3D.cxx +++ b/src/StdMeshers/StdMeshers_Hexa_3D.cxx @@ -55,6 +55,11 @@ using namespace std; #include "utilities.h" #include "Utils_ExceptHandlers.hxx" +//modified by NIZNHY-PKV Wed Nov 17 15:31:58 2004 f +#include + +static bool ComputePentahedralMesh(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape); +//modified by NIZNHY-PKV Wed Nov 17 15:32:00 2004 t //============================================================================= /*! @@ -155,15 +160,14 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh, { Unexpect aCatch(SalomeException); MESSAGE("StdMeshers_Hexa_3D::Compute"); - - bool isOk = false; + //bool isOk = false; SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); - SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape); + //SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape); //const SMESHDS_SubMesh *& subMeshDS = theSubMesh->GetSubMeshDS(); // 0. - shape and face mesh verification // 0.1 - shape must be a solid (or a shell) with 6 faces - //MESSAGE("---"); + MESSAGE("---"); vector < SMESH_subMesh * >meshFaces; for (TopExp_Explorer exp(aShape, TopAbs_FACE); exp.More(); exp.Next()) @@ -184,40 +188,56 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh, for (int i = 0; i < 6; i++) { - TopoDS_Shape aShape = meshFaces[i]->GetSubShape(); - SMESH_Algo *algo = _gen->GetAlgo(aMesh, aShape); - string algoName = algo->GetName(); - if (algoName != "Quadrangle_2D") - { - // *** delete _quads - SCRUTE(algoName); -// ASSERT(0); - return false; - } - StdMeshers_Quadrangle_2D *quadAlgo = - dynamic_cast < StdMeshers_Quadrangle_2D * >(algo); - ASSERT(quadAlgo); - try - { - _quads[i] = quadAlgo->CheckAnd2Dcompute(aMesh, aShape); - // *** to delete after usage - } - catch(SALOME_Exception & S_ex) - { - // *** delete _quads - // *** throw exception -// ASSERT(0); - return false; - } - - // 0.2.1 - number of points on the opposite edges must be the same - if (_quads[i]->nbPts[0] != _quads[i]->nbPts[2] || - _quads[i]->nbPts[1] != _quads[i]->nbPts[3]) - { - MESSAGE("different number of points on the opposite edges of face " << i); -// ASSERT(0); - return false; - } + TopoDS_Shape aFace = meshFaces[i]->GetSubShape(); + SMESH_Algo *algo = _gen->GetAlgo(aMesh, aFace); + string algoName = algo->GetName(); + bool isAllQuad = false; + if (algoName == "Quadrangle_2D") { + SMESHDS_SubMesh * sm = meshDS->MeshElements( aFace ); + if ( sm ) { + isAllQuad = true; + SMDS_ElemIteratorPtr eIt = sm->GetElements(); + while ( isAllQuad && eIt->more() ) + isAllQuad = ( eIt->next()->NbNodes() == 4 ); + } + } + if ( ! isAllQuad ) { + //modified by NIZNHY-PKV Wed Nov 17 15:31:37 2004 f + bool bIsOk; + // + bIsOk=ComputePentahedralMesh(aMesh, aShape); + if (bIsOk) { + return true; + } + //modified by NIZNHY-PKV Wed Nov 17 15:31:42 2004 t + SCRUTE(algoName); + // ASSERT(0); + return false; + } + StdMeshers_Quadrangle_2D *quadAlgo = + dynamic_cast < StdMeshers_Quadrangle_2D * >(algo); + ASSERT(quadAlgo); + try + { + _quads[i] = quadAlgo->CheckAnd2Dcompute(aMesh, aFace); + // *** to delete after usage + } + catch(SALOME_Exception & S_ex) + { + // *** delete _quads + // *** throw exception + // ASSERT(0); + return false; + } + + // 0.2.1 - number of points on the opposite edges must be the same + if (_quads[i]->nbPts[0] != _quads[i]->nbPts[2] || + _quads[i]->nbPts[1] != _quads[i]->nbPts[3]) + { + MESSAGE("different number of points on the opposite edges of face " << i); + // ASSERT(0); + return false; + } } // 1. - identify faces and vertices of the "cube" @@ -1023,3 +1043,35 @@ istream & operator >>(istream & load, StdMeshers_Hexa_3D & hyp) { return hyp.LoadFrom( load ); } + +//modified by NIZNHY-PKV Wed Nov 17 15:34:13 2004 f +/////////////////////////////////////////////////////////////////////////////// +//ZZ +//#include + +//======================================================================= +//function : ComputePentahedralMesh +//purpose : +//======================================================================= +bool ComputePentahedralMesh(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) +{ + //printf(" ComputePentahedralMesh HERE\n"); + // + bool bOK; + int iErr; + StdMeshers_Penta_3D anAlgo; + // + bOK=anAlgo.Compute(aMesh, aShape); + /* + iErr=anAlgo.ErrorStatus(); + + if (iErr) { + printf(" *** Error# %d\n", iErr); + } + else { + printf(" *** No errors# %d\n", iErr); + } + */ + return bOK; +} + diff --git a/src/StdMeshers/StdMeshers_Penta_3D.cxx b/src/StdMeshers/StdMeshers_Penta_3D.cxx new file mode 100644 index 000000000..30362f4b9 --- /dev/null +++ b/src/StdMeshers/StdMeshers_Penta_3D.cxx @@ -0,0 +1,1106 @@ +// SMESH StdMeshers_Penta_3D implementaion of SMESH idl descriptions +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshers_Penta_3D.cxx +// Module : SMESH + +using namespace std; + +#include + +#include + +#include + +#include "utilities.h" +#include "Utils_ExceptHandlers.hxx" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef map < int, int, less >::iterator \ + StdMeshers_IteratorOfDataMapOfIntegerInteger; + +//======================================================================= +// +// StdMeshers_Penta_3D +// +//======================================================================= +//function : StdMeshers_Penta_3D +//purpose : +//======================================================================= +StdMeshers_Penta_3D::StdMeshers_Penta_3D() +: myErrorStatus(1) +{ + myTol3D=0.1; +} +//======================================================================= +//function : Compute +//purpose : +//======================================================================= +bool StdMeshers_Penta_3D::Compute(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape) +{ + myErrorStatus=0; + // + bool bOK=false; + // + myShape=aShape; + SetMesh(aMesh); + // + CheckData(); + if (myErrorStatus){ + return bOK; + } + // + MakeBlock(); + if (myErrorStatus){ + return bOK; + } + // + MakeNodes(); + if (myErrorStatus){ + return bOK; + } + // + MakeConnectingMap(); + // + ClearMeshOnFxy1(); + if (myErrorStatus) { + return bOK; + } + // + MakeMeshOnFxy1(); + if (myErrorStatus) { + return bOK; + } + // + MakeVolumeMesh(); + // + return !bOK; +} +//======================================================================= +//function : MakeNodes +//purpose : +//======================================================================= +void StdMeshers_Penta_3D::MakeNodes() +{ + myErrorStatus=0; + // + const int aNbSIDs=9; + int i, j, k, ij, iNbN, aNodeID, aSize, iErr; + double aX, aY, aZ; + SMESH_Block::TShapeID aSID, aSIDs[aNbSIDs]={ + SMESH_Block::ID_V000, SMESH_Block::ID_V100, + SMESH_Block::ID_V110, SMESH_Block::ID_V010, + SMESH_Block::ID_Ex00, SMESH_Block::ID_E1y0, + SMESH_Block::ID_Ex10, SMESH_Block::ID_E0y0, + SMESH_Block::ID_Fxy0 + }; + // + SMESH_Mesh* pMesh=GetMesh(); + // + // 1. Define the sizes of mesh + // + // 1.1 Horizontal size + myJSize=0; + for (i=0; iGetSubMeshContaining(aS); + ASSERT(aSubMesh); + SMESHDS_SubMesh *aSM=aSubMesh->GetSubMeshDS(); + iNbN=aSM->NbNodes(); + myJSize+=iNbN; + } + //printf("*** Horizontal: number of nodes summary=%d\n", myJSize); + // + // 1.2 Vertical size + myISize=2; + { + const TopoDS_Shape& aS=myBlock.Shape(SMESH_Block::ID_E00z); + SMESH_subMesh *aSubMesh = pMesh->GetSubMeshContaining(aS); + ASSERT(aSubMesh); + SMESHDS_SubMesh *aSM=aSubMesh->GetSubMeshDS(); + iNbN=aSM->NbNodes(); + myISize+=iNbN; + } + //printf("*** Vertical: number of nodes on edges and vertices=%d\n", myISize); + // + aSize=myISize*myJSize; + myTNodes.resize(aSize); + // + StdMeshers_TNode aTNode; + gp_XYZ aCoords; + gp_Pnt aP3D; + // + // 2. Fill the repers on base face (Z=0) + i=0; j=0; + // vertices + for (k=0; kGetSubMeshContaining(aS)->GetSubMeshDS()->GetNodes(); + while(ite->more()) { + const SMDS_MeshNode* aNode = ite->next(); + aNodeID=aNode->GetID(); + // + aTNode.SetNode(aNode); + aTNode.SetShapeSupportID(aSID); + aTNode.SetBaseNodeID(aNodeID); + // + switch (aSID){ + case SMESH_Block::ID_V000: + aCoords.SetCoord(0., 0., 0.); + break; + case SMESH_Block::ID_V100: + aCoords.SetCoord(1., 0., 0.); + break; + case SMESH_Block::ID_V110: + aCoords.SetCoord(1., 1., 0.); + break; + case SMESH_Block::ID_V010: + aCoords.SetCoord(0., 1., 0.); + break; + case SMESH_Block::ID_Ex00: + case SMESH_Block::ID_E1y0: + case SMESH_Block::ID_Ex10: + case SMESH_Block::ID_E0y0: + case SMESH_Block::ID_Fxy0:{ + aX=aNode->X(); + aY=aNode->Y(); + aZ=aNode->Z(); + aP3D.SetCoord(aX, aY, aZ); + myBlock.ComputeParameters(aP3D, aS, aCoords); + iErr=myBlock.ErrorStatus(); + if (iErr) { + MESSAGE("StdMeshers_Penta_3D::MakeNodes()," << + "SMESHBlock: ComputeParameters operation failed"); + myErrorStatus=101; // SMESHBlock: ComputeParameters operation failed + return; + } + } + break; + default: + break; + } + aTNode.SetNormCoord(aCoords); + ij=i*myJSize+j; + myTNodes[ij]=aTNode; + ++j; + } + } + /* + //DEB + { + int iShapeSupportID, iBaseNodeID; + // + //printf("\n\n*** Base Face\n"); + i=0; + for (j=0; j aZL(myISize); + vector::iterator aItZL1, aItZL2 ; + // + const TopoDS_Shape& aE00z=myBlock.Shape(SMESH_Block::ID_E00z); + SMDS_NodeIteratorPtr aItaE00z = + pMesh->GetSubMeshContaining(aE00z)->GetSubMeshDS()->GetNodes(); + // + aZL[0]=0.; + i=1; + while (aItaE00z->more()) { + const SMDS_MeshNode* aNode=aItaE00z->next(); + aX=aNode->X(); aY=aNode->Y(); aZ=aNode->Z(); + aP3D.SetCoord(aX, aY, aZ); + myBlock.ComputeParameters(aP3D, aE00z, aCoords); + iErr=myBlock.ErrorStatus(); + if (iErr) { + MESSAGE("StdMeshers_Penta_3D::MakeNodes()," << + "SMESHBlock: ComputeParameters operation failed"); + myErrorStatus=101; // SMESHBlock: ComputeParameters operation failed + return; + } + aZL[i]=aCoords.Z(); + ++i; + } + aZL[i]=1.; + // + aItZL1=aZL.begin(); + aItZL2=aZL.end(); + // + // Sorting the layers + sort(aItZL1, aItZL2); + //DEB + /* + printf("** \n\n Layers begin\n"); + for(i=0, aItZL=aItZL1; aItZL!=aItZL2; ++aItZL, ++i) { + printf(" #%d : %lf\n", i, *aItZL); + } + printf("** Layers end\n"); + */ + //DEB + // + // + // 4. Fill the rest repers + bool bIsUpperLayer; + int iBNID; + SMESH_Block::TShapeID aSSID, aBNSSID; + StdMeshers_TNode aTN; + // + for (j=0; jGetID(); + aX=aNode->X(); + aY=aNode->Y(); + aZ=aNode->Z(); + printf("*** j:%d BNID#%d iSSID:%d ID:%d { %lf %lf %lf }, { %lf %lf %lf }\n", + j, iBNID, iSSID, aID, aXYZ.X(), aXYZ.Y(), aXYZ.Z(), aX, aY, aZ); + } + } + } + */ + //DEB t +} +//======================================================================= +//function : FindNodeOnShape +//purpose : +//======================================================================= +void StdMeshers_Penta_3D::FindNodeOnShape(const TopoDS_Shape& aS, + const gp_XYZ& aParams, + StdMeshers_TNode& aTN) +{ + myErrorStatus=0; + // + double aX, aY, aZ, aD, aTol2; + gp_Pnt aP1, aP2; + // + SMESH_Mesh* pMesh=GetMesh(); + aTol2=myTol3D*myTol3D; + SMDS_MeshNode* pNode=NULL; + // + myBlock.Point(aParams, aS, aP1); + // + SMDS_NodeIteratorPtr ite= + pMesh->GetSubMeshContaining(aS)->GetSubMeshDS()->GetNodes(); + while(ite->more()) { + const SMDS_MeshNode* aNode = ite->next(); + aX=aNode->X(); + aY=aNode->Y(); + aZ=aNode->Z(); + aP2.SetCoord(aX, aY, aZ); + aD=(double)aP1.SquareDistance(aP2); + //printf("** D=%lf ", aD, aTol2); + if (aDGetMeshDS(); + // + aExp.Init(myShape, TopAbs_SHELL); + for (; aExp.More(); aExp.Next()){ + aShell=TopoDS::Shell(aExp.Current()); + break; + } + // + // 1. Set Node In Volume + ik=myISize-1; + for (i=1; iSetNodeInVolume(aNode, aShell); + } + } + } + // + // 2. Make pentahedrons + int aID0, k , aJ[3]; + vector aN; + // + SMDS_ElemIteratorPtr itf, aItNodes; + // + const TopoDS_Face& aFxy0= + TopoDS::Face(myBlock.Shape(SMESH_Block::ID_Fxy0)); + SMESH_subMesh *aSubMesh0 = pMesh->GetSubMeshContaining(aFxy0); + SMESHDS_SubMesh *aSM0=aSubMesh0->GetSubMeshDS(); + // + itf=aSM0->GetElements(); + while(itf->more()) { + const SMDS_MeshElement* pE0=itf->next(); + // + int nbFaceNodes = pE0->NbNodes(); + if ( aN.size() < nbFaceNodes * 2 ) + aN.resize( nbFaceNodes * 2 ); + // + k=0; + aItNodes=pE0->nodesIterator(); + while (aItNodes->more()) { + const SMDS_MeshElement* pNode=aItNodes->next(); + aID0=pNode->GetID(); + aJ[k]=GetIndexOnLayer(aID0); + if (myErrorStatus) { + MESSAGE("StdMeshers_Penta_3D::MakeVolumeMesh"); + return; + } + // + ++k; + } + // + for (i=0; iAddVolume(aN[0], aN[1], aN[2], + aN[3], aN[4], aN[5]); + break; + case 4: + aV = meshDS->AddVolume(aN[0], aN[1], aN[2], aN[3], + aN[4], aN[5], aN[6], aN[7]); + break; + default: + continue; + } + meshDS->SetMeshElementOnShape(aV, aShell); + } + } +} + +//======================================================================= +//function : MakeMeshOnFxy1 +//purpose : +//======================================================================= +void StdMeshers_Penta_3D::MakeMeshOnFxy1() +{ + myErrorStatus=0; + // + int aID0, aJ, aLevel, ij, aNbNodes, k; + // + SMDS_NodeIteratorPtr itn; + SMDS_ElemIteratorPtr itf, aItNodes; + SMDSAbs_ElementType aElementType; + // + const TopoDS_Face& aFxy0= + TopoDS::Face(myBlock.Shape(SMESH_Block::ID_Fxy0)); + const TopoDS_Face& aFxy1= + TopoDS::Face(myBlock.Shape(SMESH_Block::ID_Fxy1)); + // + SMESH_Mesh* pMesh=GetMesh(); + SMESHDS_Mesh * meshDS = pMesh->GetMeshDS(); + // + SMESH_subMesh *aSubMesh0 = pMesh->GetSubMeshContaining(aFxy0); + SMESHDS_SubMesh *aSM0=aSubMesh0->GetSubMeshDS(); + // + // set nodes on aFxy1 + aLevel=myISize-1; + itn=aSM0->GetNodes(); + aNbNodes=aSM0->NbNodes(); + //printf("** aNbNodes=%d\n", aNbNodes); + while(itn->more()) { + const SMDS_MeshNode* aN0=itn->next(); + aID0=aN0->GetID(); + aJ=GetIndexOnLayer(aID0); + if (myErrorStatus) { + MESSAGE("StdMeshers_Penta_3D::MakeMeshOnFxy1() "); + return; + } + // + ij=aLevel*myJSize+aJ; + const StdMeshers_TNode& aTN1=myTNodes[ij]; + SMDS_MeshNode* aN1=(SMDS_MeshNode*)aTN1.Node(); + // + meshDS->SetNodeOnFace(aN1, aFxy1); + } + // + // set elements on aFxy1 + vector aNodes1; + // + itf=aSM0->GetElements(); + while(itf->more()) { + const SMDS_MeshElement * pE0=itf->next(); + aElementType=pE0->GetType(); + if (!aElementType==SMDSAbs_Face) { + continue; + } + aNbNodes=pE0->NbNodes(); +// if (aNbNodes!=3) { +// continue; +// } + if ( aNodes1.size() < aNbNodes ) + aNodes1.resize( aNbNodes ); + // + k=aNbNodes-1; // reverse a face + aItNodes=pE0->nodesIterator(); + while (aItNodes->more()) { + const SMDS_MeshElement* pNode=aItNodes->next(); + aID0=pNode->GetID(); + aJ=GetIndexOnLayer(aID0); + if (myErrorStatus) { + MESSAGE("StdMeshers_Penta_3D::MakeMeshOnFxy1() "); + return; + } + // + ij=aLevel*myJSize+aJ; + const StdMeshers_TNode& aTN1=myTNodes[ij]; + const SMDS_MeshNode* aN1=aTN1.Node(); + aNodes1[k]=aN1; + --k; + } + SMDS_MeshFace * face = 0; + switch ( aNbNodes ) { + case 3: + face = meshDS->AddFace(aNodes1[0], aNodes1[1], aNodes1[2]); + break; + case 4: + face = meshDS->AddFace(aNodes1[0], aNodes1[1], aNodes1[2], aNodes1[3]); + break; + default: + continue; + } + meshDS->SetMeshElementOnShape(face, aFxy1); + } +} +//======================================================================= +//function : ClearMeshOnFxy1 +//purpose : +//======================================================================= +void StdMeshers_Penta_3D::ClearMeshOnFxy1() +{ + myErrorStatus=0; + // + SMESH_subMesh* aSubMesh; + SMESH_Mesh* pMesh=GetMesh(); + // + const TopoDS_Shape& aFxy1=myBlock.Shape(SMESH_Block::ID_Fxy1); + aSubMesh = pMesh->GetSubMeshContaining(aFxy1); + if (aSubMesh) + aSubMesh->ComputeStateEngine( SMESH_subMesh::CLEAN ); +} + +//======================================================================= +//function : GetIndexOnLayer +//purpose : +//======================================================================= +int StdMeshers_Penta_3D::GetIndexOnLayer(const int aID) +{ + myErrorStatus=0; + // + int j=-1; + StdMeshers_IteratorOfDataMapOfIntegerInteger aMapIt; + // + aMapIt=myConnectingMap.find(aID); + if (aMapIt==myConnectingMap.end()) { + myErrorStatus=200; + return j; + } + j=(*aMapIt).second; + return j; +} +//======================================================================= +//function : MakeConnectingMap +//purpose : +//======================================================================= +void StdMeshers_Penta_3D::MakeConnectingMap() +{ + int j, aBNID; + // + for (j=0; jGetMeshDS(); + // + pNode = pMeshDS->AddNode(aX, aY, aZ); + aTN.SetNode(pNode); +} +//======================================================================= +//function : ShapeSupportID +//purpose : +//======================================================================= +void StdMeshers_Penta_3D::ShapeSupportID(const bool bIsUpperLayer, + const SMESH_Block::TShapeID aBNSSID, + SMESH_Block::TShapeID& aSSID) +{ + myErrorStatus=0; + // + switch (aBNSSID) { + case SMESH_Block::ID_V000: + aSSID=(bIsUpperLayer) ? SMESH_Block::ID_V001 : SMESH_Block::ID_E00z; + break; + case SMESH_Block::ID_V100: + aSSID=(bIsUpperLayer) ? SMESH_Block::ID_V101 : SMESH_Block::ID_E10z; + break; + case SMESH_Block::ID_V110: + aSSID=(bIsUpperLayer) ? SMESH_Block::ID_V111 : SMESH_Block::ID_E11z; + break; + case SMESH_Block::ID_V010: + aSSID=(bIsUpperLayer) ? SMESH_Block::ID_V011 : SMESH_Block::ID_E01z; + break; + case SMESH_Block::ID_Ex00: + aSSID=(bIsUpperLayer) ? SMESH_Block::ID_Ex01 : SMESH_Block::ID_Fx0z; + break; + case SMESH_Block::ID_Ex10: + aSSID=(bIsUpperLayer) ? SMESH_Block::ID_Ex11 : SMESH_Block::ID_Fx1z; + break; + case SMESH_Block::ID_E0y0: + aSSID=(bIsUpperLayer) ? SMESH_Block::ID_E0y1 : SMESH_Block::ID_F0yz; + break; + case SMESH_Block::ID_E1y0: + aSSID=(bIsUpperLayer) ? SMESH_Block::ID_E1y1 : SMESH_Block::ID_F1yz; + break; + case SMESH_Block::ID_Fxy0: + aSSID=SMESH_Block::ID_NONE;//(bIsUpperLayer) ? Shape_ID_Fxy1 : Shape_ID_NONE; + break; + default: + aSSID=SMESH_Block::ID_NONE; + myErrorStatus=10; // Can not find supporting shape ID + break; + } + return; +} +//======================================================================= +//function : MakeBlock +//purpose : +//======================================================================= +void StdMeshers_Penta_3D::MakeBlock() +{ + myErrorStatus=0; + // + bool bFound; + int i, j, iNbEV, iNbE, iErr, iCnt, iNbNodes, iNbF; + // + TopoDS_Vertex aV000, aV001; + TopoDS_Shape aFTr; + TopTools_IndexedDataMapOfShapeListOfShape aMVES; + TopTools_IndexedMapOfShape aME ,aMEV, aM; + TopTools_ListIteratorOfListOfShape aIt; + // + TopExp::MapShapes(myShape, TopAbs_FACE, aM); + // + // 0. Find triangulated face aFTr + SMDSAbs_ElementType aElementType; + SMESH_Mesh* pMesh=GetMesh(); + // + iCnt=0; + iNbF=aM.Extent(); + for (i=1; i<=iNbF; ++i) { + const TopoDS_Shape& aF=aM(i); + SMESH_subMesh *aSubMesh = pMesh->GetSubMeshContaining(aF); + ASSERT(aSubMesh); + SMESHDS_SubMesh *aSM=aSubMesh->GetSubMeshDS(); + SMDS_ElemIteratorPtr itf=aSM->GetElements(); + while(itf->more()) { + const SMDS_MeshElement * pElement=itf->next(); + aElementType=pElement->GetType(); + if (aElementType==SMDSAbs_Face) { + iNbNodes=pElement->NbNodes(); + if (iNbNodes==3) { + aFTr=aF; + ++iCnt; + if (iCnt>1) { + MESSAGE("StdMeshers_Penta_3D::MakeBlock() "); + myErrorStatus=5; // more than one face has triangulation + return; + } + break; // next face + } + } + } + } + // + // 1. Vetrices V00, V001; + // + TopExp::MapShapes(aFTr, TopAbs_EDGE, aME); + TopExp::MapShapesAndAncestors(myShape, TopAbs_VERTEX, TopAbs_EDGE, aMVES); + // + // 1.1 Base vertex V000 + iNbE=aME.Extent(); + if (iNbE!=4){ + MESSAGE("StdMeshers_Penta_3D::MakeBlock() "); + myErrorStatus=7; // too few edges are in base face aFTr + return; + } + const TopoDS_Edge& aE1=TopoDS::Edge(aME(1)); + aV000=TopExp::FirstVertex(aE1); + // + const TopTools_ListOfShape& aLE=aMVES.FindFromKey(aV000); + aIt.Initialize(aLE); + for (; aIt.More(); aIt.Next()) { + const TopoDS_Shape& aEx=aIt.Value(); + aMEV.Add(aEx); + } + iNbEV=aMEV.Extent(); + if (iNbEV!=3){ + MESSAGE("StdMeshers_Penta_3D::MakeBlock() "); + myErrorStatus=7; // too few edges meet in base vertex + return; + } + // + // 1.2 Vertex V001 + bFound=false; + for (j=1; j<=iNbEV; ++j) { + const TopoDS_Shape& aEx=aMEV(j); + if (!aME.Contains(aEx)) { + TopoDS_Vertex aV[2]; + // + const TopoDS_Edge& aE=TopoDS::Edge(aEx); + TopExp::Vertices(aE, aV[0], aV[1]); + for (i=0; i<2; ++i) { + if (!aV[i].IsSame(aV000)) { + aV001=aV[i]; + bFound=!bFound; + break; + } + } + } + } + // + if (!bFound) { + MESSAGE("StdMeshers_Penta_3D::MakeBlock() "); + myErrorStatus=8; // can not find reper V001 + return; + } + //DEB + //gp_Pnt aP000, aP001; + // + //aP000=BRep_Tool::Pnt(TopoDS::Vertex(aV000)); + //printf("*** aP000 { %lf, %lf, %lf }\n", aP000.X(), aP000.Y(), aP000.Z()); + //aP001=BRep_Tool::Pnt(TopoDS::Vertex(aV001)); + //printf("*** aP001 { %lf, %lf, %lf }\n", aP001.X(), aP001.Y(), aP001.Z()); + //DEB + // + aME.Clear(); + TopExp::MapShapes(myShape, TopAbs_SHELL, aME); + iNbE=aME.Extent(); + if (iNbE!=1) { + MESSAGE("StdMeshers_Penta_3D::MakeBlock() "); + myErrorStatus=9; // number of shells in source shape !=1 + return; + } + // + // 2. Load Block + const TopoDS_Shell& aShell=TopoDS::Shell(aME(1)); + myBlock.Load(aShell, aV000, aV001); + iErr=myBlock.ErrorStatus(); + if (iErr) { + MESSAGE("StdMeshers_Penta_3D::MakeBlock() "); + myErrorStatus=100; // SMESHBlock: Load operation failed + return; + } +} +//======================================================================= +//function : CheckData +//purpose : +//======================================================================= +void StdMeshers_Penta_3D::CheckData() +{ + myErrorStatus=0; + // + int i, iNb; + int iNbEx[]={8, 12, 6}; + // + TopAbs_ShapeEnum aST; + TopAbs_ShapeEnum aSTEx[]={ + TopAbs_VERTEX, TopAbs_EDGE, TopAbs_FACE + }; + TopTools_IndexedMapOfShape aM; + // + if (myShape.IsNull()){ + MESSAGE("StdMeshers_Penta_3D::CheckData() "); + myErrorStatus=2; // null shape + return; + } + // + aST=myShape.ShapeType(); + if (!(aST==TopAbs_SOLID || aST==TopAbs_SHELL)) { + MESSAGE("StdMeshers_Penta_3D::CheckData() "); + myErrorStatus=3; // not compatible type of shape + return; + } + // + for (i=0; i<3; ++i) { + aM.Clear(); + TopExp::MapShapes(myShape, aSTEx[i], aM); + iNb=aM.Extent(); + if (iNb!=iNbEx[i]){ + MESSAGE("StdMeshers_Penta_3D::CheckData() "); + myErrorStatus=4; // number of subshape is not compatible + return; + } + } +} +////////////////////////////////////////////////////////////////////////// +// +// StdMeshers_SMESHBlock +// +// +#include +#include + +//======================================================================= +//function : StdMeshers_SMESHBlock +//purpose : +//======================================================================= +StdMeshers_SMESHBlock::StdMeshers_SMESHBlock() +{ + myErrorStatus=1; +} +//======================================================================= +//function : ErrorStatus +//purpose : +//======================================================================= +int StdMeshers_SMESHBlock::ErrorStatus() const +{ + return myErrorStatus; +} +//======================================================================= +//function : Load +//purpose : +//======================================================================= +void StdMeshers_SMESHBlock::Load(const TopoDS_Shell& theShell) +{ + + TopoDS_Vertex aV000, aV001; + // + Load(theShell, aV000, aV001); +} +//======================================================================= +//function : Load +//purpose : +//======================================================================= +void StdMeshers_SMESHBlock::Load(const TopoDS_Shell& theShell, + const TopoDS_Vertex& theV000, + const TopoDS_Vertex& theV001) +{ + myErrorStatus=0; + // + myShell=theShell; + // + bool bOk; + // + myShapeIDMap.Clear(); + bOk=myTBlock.LoadBlockShapes(myShell, theV000, theV001, myShapeIDMap); + if (!bOk) { + myErrorStatus=2; + return; + } +} +//======================================================================= +//function : ComputeParameters +//purpose : +//======================================================================= +void StdMeshers_SMESHBlock::ComputeParameters(const gp_Pnt& thePnt, + gp_XYZ& theXYZ) +{ + ComputeParameters(thePnt, myShell, theXYZ); +} +//======================================================================= +//function : ComputeParameters +//purpose : +//======================================================================= +void StdMeshers_SMESHBlock::ComputeParameters(const gp_Pnt& thePnt, + const TopoDS_Shape& theShape, + gp_XYZ& theXYZ) +{ + myErrorStatus=0; + // + int aID; + bool bOk; + // + aID=ShapeID(theShape); + if (myErrorStatus) { + return; + } + bOk=myTBlock.ComputeParameters(thePnt, theXYZ, aID); + if (!bOk) { + myErrorStatus=4; // problems with computation Parameters + return; + } +} +//======================================================================= +//function : Point +//purpose : +//======================================================================= + void StdMeshers_SMESHBlock::Point(const gp_XYZ& theParams, + gp_Pnt& aP3D) +{ + TopoDS_Shape aS; + // + Point(theParams, aS, aP3D); +} +//======================================================================= +//function : Point +//purpose : +//======================================================================= + void StdMeshers_SMESHBlock::Point(const gp_XYZ& theParams, + const TopoDS_Shape& theShape, + gp_Pnt& aP3D) +{ + myErrorStatus=0; + // + int aID; + bool bOk=false; + gp_XYZ aXYZ(99.,99.,99.); + aP3D.SetXYZ(aXYZ); + // + if (theShape.IsNull()) { + bOk=myTBlock.ShellPoint(theParams, aXYZ); + } + // + else { + aID=ShapeID(theShape); + if (myErrorStatus) { + return; + } + // + if (SMESH_Block::IsVertexID(aID)) { + bOk=myTBlock.VertexPoint(aID, aXYZ); + } + else if (SMESH_Block::IsEdgeID(aID)) { + bOk=myTBlock.EdgePoint(aID, theParams, aXYZ); + } + // + else if (SMESH_Block::IsFaceID(aID)) { + bOk=myTBlock.FacePoint(aID, theParams, aXYZ); + } + } + if (!bOk) { + myErrorStatus=4; // problems with point computation + return; + } + aP3D.SetXYZ(aXYZ); +} +//======================================================================= +//function : ShapeID +//purpose : +//======================================================================= +int StdMeshers_SMESHBlock::ShapeID(const TopoDS_Shape& theShape) +{ + myErrorStatus=0; + // + int aID=-1; + TopoDS_Shape aSF, aSR; + // + aSF=theShape; + aSF.Orientation(TopAbs_FORWARD); + aSR=theShape; + aSR.Orientation(TopAbs_REVERSED); + // + if (myShapeIDMap.Contains(aSF)) { + aID=myShapeIDMap.FindIndex(aSF); + return aID; + } + if (myShapeIDMap.Contains(aSR)) { + aID=myShapeIDMap.FindIndex(aSR); + return aID; + } + myErrorStatus=2; // unknown shape; + return aID; +} +//======================================================================= +//function : Shape +//purpose : +//======================================================================= +const TopoDS_Shape& StdMeshers_SMESHBlock::Shape(const int theID) +{ + myErrorStatus=0; + // + int aNb; + // + aNb=myShapeIDMap.Extent(); + if (theID<1 || theID>aNb) { + myErrorStatus=3; // ID is out of range + return myEmptyShape; + } + // + const TopoDS_Shape& aS=myShapeIDMap.FindKey(theID); + return aS; +} diff --git a/src/StdMeshers/StdMeshers_Penta_3D.hxx b/src/StdMeshers/StdMeshers_Penta_3D.hxx new file mode 100644 index 000000000..aac472ec0 --- /dev/null +++ b/src/StdMeshers/StdMeshers_Penta_3D.hxx @@ -0,0 +1,225 @@ +// SMESH StdMeshers : implementaion of SMESH idl descriptions +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : StdMeshers_Penta_3D.hxx +// Module : SMESH + +#ifndef StdMeshers_Penta_3D_HeaderFile +#define StdMeshers_Penta_3D_HeaderFile + +#include + +typedef std::map < int, int > StdMeshers_DataMapOfIntegerInteger; + +//////////////////////////////////////////////////////////////////////// +// +// class StdMeshers_SMESHBlock +// +#include +#include +#include +#include +#include + +#include "SMESH_Block.hxx" + +class StdMeshers_SMESHBlock { + +public: + // + StdMeshers_SMESHBlock(); + + void Load (const TopoDS_Shell& theShell); + + void Load (const TopoDS_Shell& theShell, + const TopoDS_Vertex& theV000, + const TopoDS_Vertex& theV001); + + void ComputeParameters(const gp_Pnt& thePnt, + gp_XYZ& theXYZ); + + void ComputeParameters(const gp_Pnt& thePnt, + const TopoDS_Shape& theShape, + gp_XYZ& theXYZ); + + void Point(const gp_XYZ& theParams, + gp_Pnt& thePnt); + + void Point(const gp_XYZ& theParams, + const TopoDS_Shape& theShape, + gp_Pnt& thePnt); + + int ShapeID(const TopoDS_Shape& theShape); + + const TopoDS_Shape& Shape(const int theID); + + + int ErrorStatus() const; + + +protected: + TopoDS_Shell myShell; + TopTools_IndexedMapOfOrientedShape myShapeIDMap; + SMESH_Block myTBlock; + TopoDS_Shape myEmptyShape; + // + int myErrorStatus; +}; +//////////////////////////////////////////////////////////////////////// +// +// class StdMeshers_TNode +// +#include "SMDS_MeshNode.hxx" + +class StdMeshers_TNode { + +public: + + StdMeshers_TNode(){ + myNode=NULL; + myXYZ.SetCoord(99., 99., 99.); + myShapeSupportID=-1; + myBaseNodeID=-1; + } + + void SetNode(const SMDS_MeshNode* theNode) { + myNode=(SMDS_MeshNode*) theNode; + } + + const SMDS_MeshNode* Node()const { + return myNode; + } + + void SetShapeSupportID (const int theID) { + myShapeSupportID=theID; + } + + int ShapeSupportID()const { + return myShapeSupportID; + } + + void SetNormCoord (const gp_XYZ& theXYZ) { + myXYZ=theXYZ; + } + + const gp_XYZ& NormCoord ()const{ + return myXYZ; + } + + void SetBaseNodeID (const int theID) { + myBaseNodeID=theID; + } + + int BaseNodeID ()const{ + return myBaseNodeID; + } + +private: + SMDS_MeshNode* myNode; + int myShapeSupportID; + gp_XYZ myXYZ; + int myBaseNodeID; +}; + +//////////////////////////////////////////////////////////////////////// +// +// class StdMeshers_Penta_3D +// +#include "SMESH_Mesh.hxx" +#include +// +class StdMeshers_Penta_3D { +// + public: // methods + StdMeshers_Penta_3D(); + + //~StdMeshers_Penta_3D(); + + bool Compute(SMESH_Mesh& , const TopoDS_Shape& ); + + int ErrorStatus() const { + return myErrorStatus; + } + + void SetTolerance(const double theTol3D) { + myTol3D=theTol3D; + } + + double Tolerance() const { + return myTol3D; + } + + + protected: // methods + + void CheckData(); + + void MakeBlock(); + + void MakeNodes(); + + void ShapeSupportID(const bool theIsUpperLayer, + const SMESH_Block::TShapeID theBNSSID, + SMESH_Block::TShapeID& theSSID); + + void FindNodeOnShape(const TopoDS_Shape& aS, + const gp_XYZ& aParams, + StdMeshers_TNode& aTN); + + void CreateNode(const bool theIsUpperLayer, + const gp_XYZ& aParams, + StdMeshers_TNode& aTN); + + void ClearMeshOnFxy1(); + + void MakeMeshOnFxy1(); + + void MakeConnectingMap(); + + int GetIndexOnLayer(const int aID); + + void MakeVolumeMesh(); + + void SetMesh(SMESH_Mesh& theMesh) { + myMesh=(void *)&theMesh; + } + + SMESH_Mesh* GetMesh()const { + return (SMESH_Mesh*)myMesh; + } + + protected: // fields + TopoDS_Shape myShape; + StdMeshers_SMESHBlock myBlock; + void * myMesh; + int myErrorStatus; + // + vector myTNodes; + int myISize; + int myJSize; + double myTol3D; // Tolerance value + StdMeshers_DataMapOfIntegerInteger myConnectingMap; + +}; + +#endif diff --git a/src/StdMeshers/StdMeshers_Regular_1D.cxx b/src/StdMeshers/StdMeshers_Regular_1D.cxx index 6a6f92a79..d7d2e844e 100644 --- a/src/StdMeshers/StdMeshers_Regular_1D.cxx +++ b/src/StdMeshers/StdMeshers_Regular_1D.cxx @@ -1,23 +1,23 @@ // SMESH SMESH : implementaion of SMESH idl descriptions // // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org // // // @@ -38,7 +38,6 @@ using namespace std; #include "StdMeshers_Arithmetic1D.hxx" #include "StdMeshers_StartEndLength.hxx" #include "StdMeshers_Deflection1D.hxx" -#include "StdMeshers_Propagation.hxx" #include "SMDS_MeshElement.hxx" #include "SMDS_MeshNode.hxx" @@ -48,18 +47,13 @@ using namespace std; #include "utilities.h" #include -#include - #include #include -#include #include - #include #include #include #include - #include #include @@ -68,7 +62,7 @@ using namespace std; //============================================================================= /*! - * + * */ //============================================================================= @@ -88,7 +82,7 @@ StdMeshers_Regular_1D::StdMeshers_Regular_1D(int hypId, int studyId, //============================================================================= /*! - * + * */ //============================================================================= @@ -98,7 +92,7 @@ StdMeshers_Regular_1D::~StdMeshers_Regular_1D() //============================================================================= /*! - * + * */ //============================================================================= @@ -186,7 +180,7 @@ bool StdMeshers_Regular_1D::CheckHypothesis //============================================================================= /*! - * + * */ //============================================================================= bool StdMeshers_Regular_1D::computeInternalParameters(const TopoDS_Edge& theEdge, @@ -316,7 +310,7 @@ bool StdMeshers_Regular_1D::computeInternalParameters(const TopoDS_Edge& theEdge theParams.push_back( param ); } return true; - + } case ARITHMETIC_1D: { @@ -363,7 +357,7 @@ bool StdMeshers_Regular_1D::computeInternalParameters(const TopoDS_Edge& theEdge //============================================================================= /*! - * + * */ //============================================================================= @@ -419,7 +413,7 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh // only internal nodes receive an edge position with param on curve const SMDS_MeshNode * idPrev = idFirst; - + for (list::iterator itU = params.begin(); itU != params.end(); itU++) { double param = *itU; @@ -429,7 +423,7 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh SMDS_MeshNode * node = meshDS->AddNode(P.X(), P.Y(), P.Z()); meshDS->SetNodeOnEdge(node, E); - // **** edgePosition associe au point = param. + // **** edgePosition associe au point = param. SMDS_EdgePosition* epos = dynamic_cast(node->GetPosition().get()); epos->SetUParameter(param); @@ -476,130 +470,48 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh //============================================================================= /*! - * GetUsedHypothesis + * See comments in SMESH_Algo.cxx */ //============================================================================= -const list & StdMeshers_Regular_1D::GetUsedHypothesis - (SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) +const list & StdMeshers_Regular_1D::GetUsedHypothesis( + SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) { _usedHypList.clear(); - _usedHypList = GetAppliedHypothesis(aMesh, aShape); // copy + _usedHypList = GetAppliedHypothesis(aMesh, aShape); // copy int nbHyp = _usedHypList.size(); - - // try to find being propagated hypothesis - string propName = StdMeshers_Propagation::GetName(); - if (nbHyp == 0) { - // Get all opposite edges - TopTools_ListOfShape anOppositeEdges; - TopoDS_Shape mainShape = aMesh.GetMeshDS()->ShapeToMesh(); - GetOppositeEdges(mainShape, aShape, anOppositeEdges); - TopTools_ListIteratorOfListOfShape oppIt (anOppositeEdges); - for (; oppIt.More(); oppIt.Next()) { - const TopoDS_Shape& oppE = oppIt.Value(); - - // Find Propagation hypothesis on the opposite edge - if (IsPropagated(aMesh, oppE)) { - - // Get hypothesis, used by the opposite edge - _usedHypList = SMESH_Algo::GetUsedHypothesis(aMesh, oppE); - nbHyp = _usedHypList.size(); - if (nbHyp == 1) - break; - } + if (nbHyp == 0) + { + // Check, if propagated from some other edge + TopoDS_Shape aMainEdge; + if (aShape.ShapeType() == TopAbs_EDGE && + aMesh.IsPropagatedHypothesis(aShape, aMainEdge)) + { + // Propagation of 1D hypothesis from on this edge + _usedHypList = GetAppliedHypothesis(aMesh, aMainEdge); // copy + nbHyp = _usedHypList.size(); } } - - // try to find relevant 1D hypothesis on ancestors - if (nbHyp == 0) { - TopTools_ListIteratorOfListOfShape ancIt (aMesh.GetAncestors(aShape)); - for (; ancIt.More(); ancIt.Next()) { + if (nbHyp == 0) + { + TopTools_ListIteratorOfListOfShape ancIt( aMesh.GetAncestors( aShape )); + for (; ancIt.More(); ancIt.Next()) + { const TopoDS_Shape& ancestor = ancIt.Value(); - _usedHypList = GetAppliedHypothesis(aMesh, ancestor); // copy + _usedHypList = GetAppliedHypothesis(aMesh, ancestor); // copy nbHyp = _usedHypList.size(); if (nbHyp == 1) break; } } - if (nbHyp > 1) - _usedHypList.clear(); //only one compatible hypothesis allowed + _usedHypList.clear(); //only one compatible hypothesis allowed return _usedHypList; } //============================================================================= /*! - * Is Propagation hypothesis assigned to theShape or its ancestors - */ -//============================================================================= -Standard_Boolean StdMeshers_Regular_1D::IsPropagated (SMESH_Mesh & theMesh, - const TopoDS_Shape & theShape) -{ - const SMESHDS_Mesh * meshDS = theMesh.GetMeshDS(); - - // try to find Propagation hypothesis on theShape - const list & listHyp = meshDS->GetHypothesis(theShape); - - list::const_iterator it = listHyp.begin(); - for (; it != listHyp.end(); it++) { - const SMESHDS_Hypothesis *anHyp = *it; - if (anHyp->GetName() == StdMeshers_Propagation::GetName()) - return Standard_True; - } - - // try to find Propagation hypothesis on ancestors - TopTools_ListIteratorOfListOfShape ancIt (theMesh.GetAncestors(theShape)); - for (; ancIt.More(); ancIt.Next()) { - const TopoDS_Shape& ancestor = ancIt.Value(); - const list & listAncHyp = meshDS->GetHypothesis(ancestor); - - list::const_iterator itAnc = listAncHyp.begin(); - for (; itAnc != listAncHyp.end(); itAnc++) { - const SMESHDS_Hypothesis *anHyp = *itAnc; - if (anHyp->GetName() == StdMeshers_Propagation::GetName()) - return Standard_True; - } - } - - return Standard_False; -} - -//============================================================================= -/*! - * GetOppositeEdges() - get all edges of theShape, - * laying on any quadrangle face in front of theEdge - */ -//============================================================================= -void StdMeshers_Regular_1D::GetOppositeEdges (const TopoDS_Shape& theShape, - const TopoDS_Shape& theEdge, - TopTools_ListOfShape& theOppositeEdges) const -{ - TopExp_Explorer aWires (theShape, TopAbs_WIRE); - for (; aWires.More(); aWires.Next()) { - const TopoDS_Shape& aWire = aWires.Current(); - BRepTools_WireExplorer aWE (TopoDS::Wire(aWire)); - Standard_Integer nb = 1, found = 0; - TopTools_Array1OfShape anEdges (1,4); - for (; aWE.More(); aWE.Next(), nb++) { - if (nb > 4) { - found = 0; - break; - } - anEdges(nb) = aWE.Current(); - if (anEdges(nb).IsSame(theEdge)) - found = nb; - } - if (nb == 5 && found > 0) { - Standard_Integer opp = found + 2; - if (opp > 4) opp -= 4; - theOppositeEdges.Append(anEdges(opp)); - } - } -} - -//============================================================================= -/*! - * + * */ //============================================================================= @@ -610,7 +522,7 @@ ostream & StdMeshers_Regular_1D::SaveTo(ostream & save) //============================================================================= /*! - * + * */ //============================================================================= @@ -621,7 +533,7 @@ istream & StdMeshers_Regular_1D::LoadFrom(istream & load) //============================================================================= /*! - * + * */ //============================================================================= @@ -632,7 +544,7 @@ ostream & operator <<(ostream & save, StdMeshers_Regular_1D & hyp) //============================================================================= /*! - * + * */ //============================================================================= diff --git a/src/StdMeshers/StdMeshers_Regular_1D.hxx b/src/StdMeshers/StdMeshers_Regular_1D.hxx index b038a91d2..548d59802 100644 --- a/src/StdMeshers/StdMeshers_Regular_1D.hxx +++ b/src/StdMeshers/StdMeshers_Regular_1D.hxx @@ -32,9 +32,6 @@ #include "SMESH_1D_Algo.hxx" -#include -#include - class TopoDS_Edge; class StdMeshers_Regular_1D: @@ -52,7 +49,7 @@ public: const TopoDS_Shape& aShape); virtual const std::list & - GetUsedHypothesis (SMESH_Mesh & aMesh, const TopoDS_Shape & aShape); + GetUsedHypothesis(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape); ostream & SaveTo(ostream & save); istream & LoadFrom(istream & load); @@ -61,13 +58,6 @@ public: protected: - Standard_Boolean IsPropagated (SMESH_Mesh & theMesh, - const TopoDS_Shape & theShape); - - void GetOppositeEdges (const TopoDS_Shape& theShape, - const TopoDS_Shape& theEdge, - TopTools_ListOfShape& theOppositeEdges) const; - bool computeInternalParameters (const TopoDS_Edge& theEdge, std::list< double > & theParameters ) const; -- 2.30.2