X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSMESH%2FSMESH_Pattern.cxx;h=06595678e81a14811531a9e80b0877ad59138b10;hb=ed456586bfb1411c5bff73b221658766689a6253;hp=7f20a5cad0f97a57c5ed29fa2597704481299df7;hpb=e4737e85f0da6d3f90fd08f6be1c2825195fe16f;p=modules%2Fsmesh.git 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 ); - } -}