X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMDS%2FSMDS_VolumeTool.cxx;h=381b262ee334a19aef0bdaecace677be468baac4;hp=2b549d217e7ac10998624bc43c9c2a30dfde19a0;hb=2754c581d371f9bf52b3c538a7bde55f10f6523c;hpb=5467bb25d4a8ca4a84de65bc44b725bdd9d69a29 diff --git a/src/SMDS/SMDS_VolumeTool.cxx b/src/SMDS/SMDS_VolumeTool.cxx index 2b549d217..381b262ee 100644 --- a/src/SMDS/SMDS_VolumeTool.cxx +++ b/src/SMDS/SMDS_VolumeTool.cxx @@ -1,3 +1,22 @@ +// Copyright (C) 2005 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.salome-platform.org/ +// // File : SMDS_VolumeTool.cxx // Created : Tue Jul 13 12:22:13 2004 // Author : Edward AGAPOV (eap) @@ -372,6 +391,66 @@ void SMDS_VolumeTool::Inverse () } } +//======================================================================= +//function : GetVolumeType +//purpose : +//======================================================================= + +SMDS_VolumeTool::VolumeType SMDS_VolumeTool::GetVolumeType() const +{ + if ( myPolyedre ) + return POLYHEDA; + + if ( myVolume ) { + static const VolumeType types[] = { + TETRA, // myVolumeNbNodes = 4 + PYRAM, // myVolumeNbNodes = 5 + PENTA, // myVolumeNbNodes = 6 + UNKNOWN, // myVolumeNbNodes = 7 + HEXA // myVolumeNbNodes = 8 + }; + return types[ myVolumeNbNodes - 4 ]; + } + + return UNKNOWN; +} + +//======================================================================= +//function : getTetraVolume +//purpose : +//======================================================================= + +static double getTetraVolume(const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2, + const SMDS_MeshNode* n3, + const SMDS_MeshNode* n4) +{ + double X1 = n1->X(); + double Y1 = n1->Y(); + double Z1 = n1->Z(); + + double X2 = n2->X(); + double Y2 = n2->Y(); + double Z2 = n2->Z(); + + double X3 = n3->X(); + double Y3 = n3->Y(); + double Z3 = n3->Z(); + + double X4 = n4->X(); + double Y4 = n4->Y(); + double Z4 = n4->Z(); + + double Q1 = -(X1-X2)*(Y3*Z4-Y4*Z3); + double Q2 = (X1-X3)*(Y2*Z4-Y4*Z2); + double R1 = -(X1-X4)*(Y2*Z3-Y3*Z2); + double R2 = -(X2-X3)*(Y1*Z4-Y4*Z1); + double S1 = (X2-X4)*(Y1*Z3-Y3*Z1); + double S2 = -(X3-X4)*(Y1*Z2-Y2*Z1); + + return (Q1+Q2+R1+R2+S1+S2)/6.0; +} + //======================================================================= //function : GetSize //purpose : Return element volume @@ -379,7 +458,71 @@ void SMDS_VolumeTool::Inverse () double SMDS_VolumeTool::GetSize() const { - return 0; + double V = 0.; + if ( !myVolume ) + return 0.; + + if ( myVolume->IsPoly() ) + { + if ( !myPolyedre ) + return 0.; + + // split a polyhedron into tetrahedrons + + SMDS_VolumeTool* me = const_cast< SMDS_VolumeTool* > ( this ); + XYZ baryCenter; + me->GetBaryCenter(baryCenter.x, baryCenter.y, baryCenter.z); + SMDS_MeshNode bcNode ( baryCenter.x, baryCenter.y, baryCenter.z ); + + for ( int f = 0; f < NbFaces(); ++f ) + { + bool externalFace = me->IsFaceExternal( f ); // it calls setFace() + for ( int n = 2; n < myFaceNbNodes; ++n ) + { + double Vn = getTetraVolume( myFaceNodes[ 0 ], + myFaceNodes[ n-1 ], + myFaceNodes[ n ], + & bcNode ); +/// cout <<"++++ " << Vn << " nodes " <GetID() << " " <GetID() << " " <GetID() << " < " << V << endl; + V += externalFace ? -Vn : Vn; + } + } + } + else + { + const static int ind[] = { + 0, 1, 3, 6, 11 }; + const static int vtab[][4] = { + // tetrahedron + { 0, 1, 2, 3 }, + // pyramid + { 0, 1, 3, 4 }, + { 1, 2, 3, 4 }, + // pentahedron + { 0, 1, 2, 3 }, + { 1, 5, 3, 4 }, + { 1, 5, 2, 3 }, + // hexahedron + { 1, 4, 3, 0 }, + { 4, 1, 6, 5 }, + { 1, 3, 6, 2 }, + { 4, 6, 3, 7 }, + { 1, 4, 6, 3 } + }; + + int type = GetVolumeType(); + int n1 = ind[type]; + int n2 = ind[type+1]; + + for (int i = n1; i < n2; i++) + { + V -= getTetraVolume( myVolumeNodes[ vtab[i][0] ], + myVolumeNodes[ vtab[i][1] ], + myVolumeNodes[ vtab[i][2] ], + myVolumeNodes[ vtab[i][3] ]); + } + } + return V; } //======================================================================= @@ -536,7 +679,7 @@ bool SMDS_VolumeTool::GetFaceNormal (int faceIndex, double & X, double & Y, doub XYZ aVec13( p3 - p1 ); XYZ cross = aVec12.Crossed( aVec13 ); - if ( myFaceNbNodes[ faceIndex ] == 4 ) { + if ( myFaceNbNodes == 4 ) { XYZ p4 ( myFaceNodes[3] ); XYZ aVec14( p4 - p1 ); XYZ cross2 = aVec13.Crossed( aVec14 ); @@ -900,16 +1043,8 @@ bool SMDS_VolumeTool::setFace( int faceIndex ) // check orientation bool isGoodOri = true; - if (myExternalFaces) { - // get natural orientation - XYZ aNormal, baryCenter, p0 (myPolyedre->GetFaceNode(faceIndex + 1, 1)); - SMDS_VolumeTool vTool (myPolyedre); - vTool.GetFaceNormal(faceIndex, aNormal.x, aNormal.y, aNormal.z); - vTool.GetBaryCenter(baryCenter.x, baryCenter.y, baryCenter.z); - XYZ insideVec (baryCenter - p0); - if (insideVec.Dot(aNormal) > 0) - isGoodOri = false; - } + if (myExternalFaces) + isGoodOri = IsFaceExternal( faceIndex ); // set face nodes int iNode;