Salome HOME
30362f4b92bb85f72222109ac8c8a29d24026b7a
[modules/smesh.git] / src / StdMeshers / StdMeshers_Penta_3D.cxx
1 //  SMESH StdMeshers_Penta_3D implementaion of SMESH idl descriptions
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
6 //  This library is free software; you can redistribute it and/or 
7 //  modify it under the terms of the GNU Lesser General Public 
8 //  License as published by the Free Software Foundation; either 
9 //  version 2.1 of the License. 
10 // 
11 //  This library is distributed in the hope that it will be useful, 
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of 
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
14 //  Lesser General Public License for more details. 
15 // 
16 //  You should have received a copy of the GNU Lesser General Public 
17 //  License along with this library; if not, write to the Free Software 
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
19 // 
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : StdMeshers_Penta_3D.cxx
25 //  Module : SMESH
26
27 using namespace std;
28
29 #include <StdMeshers_Penta_3D.hxx>
30
31 #include <stdio.h>
32
33 #include <algorithm>
34
35 #include "utilities.h"
36 #include "Utils_ExceptHandlers.hxx"
37
38 #include <TopAbs_ShapeEnum.hxx>
39 #include <TopTools_IndexedMapOfShape.hxx>
40 #include <TopExp.hxx>
41 #include <SMESH_Mesh.hxx>
42 #include <SMESH_subMesh.hxx>
43 #include <SMESHDS_SubMesh.hxx>
44
45 #include <SMDS_MeshElement.hxx>
46 #include <TopTools_IndexedMapOfShape.hxx>
47 #include <TopTools_ListOfShape.hxx>
48 #include <TopoDS_Vertex.hxx>
49 #include <TopoDS_Edge.hxx>
50 #include <TopoDS.hxx>
51 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
52 #include <TopTools_ListIteratorOfListOfShape.hxx>
53 #include <gp_Pnt.hxx>
54 #include <BRep_Tool.hxx>
55 #include <TopoDS_Shell.hxx>
56
57 typedef map < int, int, less<int> >::iterator   \
58   StdMeshers_IteratorOfDataMapOfIntegerInteger;
59
60 //=======================================================================
61 //
62 //           StdMeshers_Penta_3D 
63 //
64 //=======================================================================
65 //function : StdMeshers_Penta_3D
66 //purpose  : 
67 //=======================================================================
68 StdMeshers_Penta_3D::StdMeshers_Penta_3D()
69 : myErrorStatus(1)
70 {
71   myTol3D=0.1;
72 }
73 //=======================================================================
74 //function : Compute
75 //purpose  : 
76 //=======================================================================
77 bool StdMeshers_Penta_3D::Compute(SMESH_Mesh& aMesh, 
78                                   const TopoDS_Shape& aShape)
79 {
80   myErrorStatus=0;
81   //
82   bool bOK=false;
83   //
84   myShape=aShape;
85   SetMesh(aMesh);
86   //
87   CheckData();
88   if (myErrorStatus){
89     return bOK;
90   }
91   //
92   MakeBlock();
93     if (myErrorStatus){
94     return bOK;
95   }
96   //
97   MakeNodes();
98   if (myErrorStatus){
99     return bOK;
100   }
101   //
102   MakeConnectingMap();
103   //
104   ClearMeshOnFxy1();
105   if (myErrorStatus) {
106     return bOK;
107   }
108   //
109   MakeMeshOnFxy1();
110   if (myErrorStatus) {
111     return bOK;
112   }
113   //
114   MakeVolumeMesh();
115   //
116   return !bOK;
117 }
118 //=======================================================================
119 //function : MakeNodes
120 //purpose  : 
121 //=======================================================================
122 void StdMeshers_Penta_3D::MakeNodes()
123 {
124   myErrorStatus=0;
125   //
126   const int aNbSIDs=9;
127   int i, j, k, ij, iNbN, aNodeID, aSize, iErr;
128   double aX, aY, aZ;
129   SMESH_Block::TShapeID aSID, aSIDs[aNbSIDs]={
130     SMESH_Block::ID_V000, SMESH_Block::ID_V100, 
131     SMESH_Block::ID_V110, SMESH_Block::ID_V010,
132     SMESH_Block::ID_Ex00, SMESH_Block::ID_E1y0, 
133     SMESH_Block::ID_Ex10, SMESH_Block::ID_E0y0,
134     SMESH_Block::ID_Fxy0
135   }; 
136   //
137   SMESH_Mesh* pMesh=GetMesh();
138   //
139   // 1. Define the sizes of mesh
140   //
141   // 1.1 Horizontal size
142   myJSize=0;
143   for (i=0; i<aNbSIDs; ++i) {
144     const TopoDS_Shape& aS=myBlock.Shape(aSIDs[i]);
145     SMESH_subMesh *aSubMesh = pMesh->GetSubMeshContaining(aS);
146     ASSERT(aSubMesh);
147     SMESHDS_SubMesh *aSM=aSubMesh->GetSubMeshDS();
148     iNbN=aSM->NbNodes();
149     myJSize+=iNbN;
150   }
151   //printf("***  Horizontal: number of nodes summary=%d\n", myJSize);
152   //
153   // 1.2 Vertical size
154   myISize=2;
155   {
156     const TopoDS_Shape& aS=myBlock.Shape(SMESH_Block::ID_E00z);
157     SMESH_subMesh *aSubMesh = pMesh->GetSubMeshContaining(aS);
158     ASSERT(aSubMesh);
159     SMESHDS_SubMesh *aSM=aSubMesh->GetSubMeshDS();
160     iNbN=aSM->NbNodes();
161     myISize+=iNbN;
162   }
163   //printf("***  Vertical: number of nodes on edges and vertices=%d\n", myISize);
164   //
165   aSize=myISize*myJSize;
166   myTNodes.resize(aSize);
167   //
168   StdMeshers_TNode aTNode;
169   gp_XYZ aCoords;
170   gp_Pnt aP3D;
171   //
172   // 2. Fill the repers on base face (Z=0)
173   i=0; j=0;
174   // vertices
175   for (k=0; k<aNbSIDs; ++k) {
176     aSID=aSIDs[k];
177     const TopoDS_Shape& aS=myBlock.Shape(aSID);
178     SMDS_NodeIteratorPtr ite =pMesh->GetSubMeshContaining(aS)->GetSubMeshDS()->GetNodes();
179     while(ite->more()) {
180       const SMDS_MeshNode* aNode = ite->next();
181       aNodeID=aNode->GetID();
182       //
183       aTNode.SetNode(aNode);
184       aTNode.SetShapeSupportID(aSID);
185       aTNode.SetBaseNodeID(aNodeID);
186       //
187       switch (aSID){
188         case SMESH_Block::ID_V000:
189           aCoords.SetCoord(0., 0., 0.);
190           break;
191         case SMESH_Block::ID_V100:
192           aCoords.SetCoord(1., 0., 0.);
193           break; 
194         case SMESH_Block::ID_V110:
195           aCoords.SetCoord(1., 1., 0.);
196           break; 
197         case SMESH_Block::ID_V010:
198           aCoords.SetCoord(0., 1., 0.);
199           break;
200         case SMESH_Block::ID_Ex00:  
201         case SMESH_Block::ID_E1y0:
202         case SMESH_Block::ID_Ex10:
203         case SMESH_Block::ID_E0y0:
204         case SMESH_Block::ID_Fxy0:{
205           aX=aNode->X();
206           aY=aNode->Y();
207           aZ=aNode->Z();
208           aP3D.SetCoord(aX, aY, aZ);
209           myBlock.ComputeParameters(aP3D, aS, aCoords);
210           iErr=myBlock.ErrorStatus();
211           if (iErr) {
212             MESSAGE("StdMeshers_Penta_3D::MakeNodes()," <<
213                     "SMESHBlock: ComputeParameters operation failed");
214             myErrorStatus=101; // SMESHBlock: ComputeParameters operation failed
215             return;
216           }
217         }
218           break;
219         default:
220           break;
221       }
222       aTNode.SetNormCoord(aCoords);
223       ij=i*myJSize+j;
224       myTNodes[ij]=aTNode;
225       ++j;
226     }
227   }
228   /*
229   //DEB
230   {
231     int iShapeSupportID, iBaseNodeID;
232     //
233     //printf("\n\n*** Base Face\n");
234     i=0;
235     for (j=0; j<myJSize; ++j) {
236       ij=i*myJSize+j;
237       const StdMeshers_TNode& aTNode=myTNodes[ij];
238       iShapeSupportID=aTNode.ShapeSupportID();
239       iBaseNodeID=aTNode.BaseNodeID();
240       const gp_XYZ& aXYZ=aTNode.NormCoord();
241       printf("*** j:%d bID#%d iSS:%d { %lf %lf %lf }\n",
242              j,  iBaseNodeID, iShapeSupportID, aXYZ.X(),  aXYZ.Y(), aXYZ.Z());
243     }
244   }
245   */
246   //DEB
247   //return; //zz
248   //
249   // 3. Finding of Z-layers
250   vector<double> aZL(myISize);
251   vector<double>::iterator aItZL1, aItZL2 ;
252   //
253   const TopoDS_Shape& aE00z=myBlock.Shape(SMESH_Block::ID_E00z);
254   SMDS_NodeIteratorPtr aItaE00z =
255     pMesh->GetSubMeshContaining(aE00z)->GetSubMeshDS()->GetNodes();
256   //
257   aZL[0]=0.;
258   i=1;
259   while (aItaE00z->more()) {
260     const SMDS_MeshNode* aNode=aItaE00z->next();
261     aX=aNode->X(); aY=aNode->Y(); aZ=aNode->Z();
262     aP3D.SetCoord(aX, aY, aZ);
263     myBlock.ComputeParameters(aP3D, aE00z, aCoords);
264     iErr=myBlock.ErrorStatus();
265     if (iErr) {
266       MESSAGE("StdMeshers_Penta_3D::MakeNodes()," <<
267               "SMESHBlock: ComputeParameters operation failed");
268       myErrorStatus=101; // SMESHBlock: ComputeParameters operation failed
269       return;
270     }
271     aZL[i]=aCoords.Z();
272     ++i;
273   }
274   aZL[i]=1.;
275   //
276   aItZL1=aZL.begin();
277   aItZL2=aZL.end();
278   //
279   // Sorting the layers
280   sort(aItZL1, aItZL2);
281   //DEB
282   /*
283   printf("** \n\n Layers begin\n");
284   for(i=0, aItZL=aItZL1; aItZL!=aItZL2; ++aItZL, ++i) {
285     printf(" #%d : %lf\n", i, *aItZL);
286   } 
287   printf("** Layers end\n");
288   */
289   //DEB
290   //
291   //
292   // 4. Fill the rest repers
293   bool bIsUpperLayer;
294   int iBNID;
295   SMESH_Block::TShapeID aSSID, aBNSSID;
296   StdMeshers_TNode aTN;
297   //
298   for (j=0; j<myJSize; ++j) {
299     for (i=1; i<myISize; ++i) {
300       //
301       // base node info
302       const StdMeshers_TNode& aBN=myTNodes[j];
303       aBNSSID=(SMESH_Block::TShapeID)aBN.ShapeSupportID();
304       iBNID=aBN.BaseNodeID();
305       const gp_XYZ& aBNXYZ=aBN.NormCoord();
306       //
307       // fill current node info
308       //   -index in aTNodes
309       ij=i*myJSize+j; 
310       //   -normalized coordinates  
311       aX=aBNXYZ.X();  
312       aY=aBNXYZ.Y();
313       aZ=aZL[i];
314       aCoords.SetCoord(aX, aY, aZ); 
315       //
316       //   suporting shape ID
317       bIsUpperLayer=(i==(myISize-1));
318       ShapeSupportID(bIsUpperLayer, aBNSSID, aSSID);
319       if (myErrorStatus) {
320         MESSAGE("StdMeshers_Penta_3D::MakeNodes() ");
321         return;
322       }
323       //
324       aTN.SetShapeSupportID(aSSID);
325       aTN.SetNormCoord(aCoords);
326       aTN.SetBaseNodeID(iBNID);
327       //
328       if (aSSID!=SMESH_Block::ID_NONE){
329         // try to find the node
330         const TopoDS_Shape& aS=myBlock.Shape((int)aSSID);
331         FindNodeOnShape(aS, aCoords, aTN);
332       }
333       else{
334         // create node and get it id
335         CreateNode (bIsUpperLayer, aCoords, aTN);
336       }
337       if (myErrorStatus) {
338         MESSAGE("StdMeshers_Penta_3D::MakeNodes() ");
339         return;
340       }
341       //
342       myTNodes[ij]=aTN;
343     }
344   }
345   //DEB
346   /*
347   {
348     int iSSID, iBNID, aID;
349     //
350     for (i=0; i<myISize; ++i) {
351       printf(" Layer# %d\n", i);
352       for (j=0; j<myJSize; ++j) {
353         ij=i*myJSize+j; 
354         const StdMeshers_TNode& aTN=myTNodes[ij];
355         //const StdMeshers_TNode& aTN=aTNodes[ij];
356         const gp_XYZ& aXYZ=aTN.NormCoord();
357         iSSID=aTN.ShapeSupportID();
358         iBNID=aTN.BaseNodeID();
359         //
360         const SMDS_MeshNode* aNode=aTN.Node();
361         aID=aNode->GetID(); 
362         aX=aNode->X();
363         aY=aNode->Y();
364         aZ=aNode->Z();
365         printf("*** j:%d BNID#%d iSSID:%d ID:%d { %lf %lf %lf },  { %lf %lf %lf }\n",
366                j,  iBNID, iSSID, aID, aXYZ.X(),  aXYZ.Y(), aXYZ.Z(), aX, aY, aZ);
367       }
368     }
369   }
370   */
371   //DEB t
372 }
373 //=======================================================================
374 //function : FindNodeOnShape
375 //purpose  : 
376 //=======================================================================
377 void StdMeshers_Penta_3D::FindNodeOnShape(const TopoDS_Shape& aS,
378                                           const gp_XYZ& aParams,
379                                           StdMeshers_TNode& aTN)
380 {
381   myErrorStatus=0;
382   //
383   double aX, aY, aZ, aD, aTol2;
384   gp_Pnt aP1, aP2;
385   //
386   SMESH_Mesh* pMesh=GetMesh();
387   aTol2=myTol3D*myTol3D;
388   SMDS_MeshNode* pNode=NULL;
389   //
390   myBlock.Point(aParams, aS, aP1);
391   //
392   SMDS_NodeIteratorPtr ite=
393     pMesh->GetSubMeshContaining(aS)->GetSubMeshDS()->GetNodes();
394   while(ite->more()) {
395     const SMDS_MeshNode* aNode = ite->next();
396     aX=aNode->X();
397     aY=aNode->Y();
398     aZ=aNode->Z();
399     aP2.SetCoord(aX, aY, aZ);
400     aD=(double)aP1.SquareDistance(aP2);
401     //printf("** D=%lf ", aD, aTol2);
402     if (aD<aTol2) {
403       pNode=(SMDS_MeshNode*)aNode;
404       aTN.SetNode(pNode);
405       //printf(" Ok\n");
406       return; 
407     }
408   }
409   //
410   //printf(" KO\n");
411   aTN.SetNode(pNode);
412   MESSAGE("StdMeshers_Penta_3D::FindNodeOnShape(), can not find the node");
413   myErrorStatus=11; // can not find the node;
414 }
415
416 //=======================================================================
417 //function : MakeVolumeMesh
418 //purpose  : 
419 //=======================================================================
420 void StdMeshers_Penta_3D::MakeVolumeMesh()
421 {
422   myErrorStatus=0;
423   //
424   int i, j, ij, ik, i1, i2, aSSID; 
425   //
426   TopoDS_Shell aShell;
427   TopExp_Explorer aExp;
428   //
429   SMESH_Mesh*   pMesh =GetMesh();
430   SMESHDS_Mesh* meshDS=pMesh->GetMeshDS();
431   //
432   aExp.Init(myShape, TopAbs_SHELL);
433   for (; aExp.More(); aExp.Next()){
434     aShell=TopoDS::Shell(aExp.Current());
435     break;
436   }
437   //
438   // 1. Set Node In Volume
439   ik=myISize-1;
440   for (i=1; i<ik; ++i){
441     for (j=0; j<myJSize; ++j){
442       ij=i*myJSize+j;
443       const StdMeshers_TNode& aTN=myTNodes[ij];
444       aSSID=aTN.ShapeSupportID();
445       if (aSSID==SMESH_Block::ID_NONE) {
446         SMDS_MeshNode* aNode=(SMDS_MeshNode*)aTN.Node();
447         meshDS->SetNodeInVolume(aNode, aShell);
448       }
449     }
450   }
451   //
452   // 2. Make pentahedrons
453   int aID0, k , aJ[3];
454   vector<const SMDS_MeshNode*> aN;
455   //
456   SMDS_ElemIteratorPtr itf, aItNodes;
457   //
458   const TopoDS_Face& aFxy0=
459     TopoDS::Face(myBlock.Shape(SMESH_Block::ID_Fxy0));
460   SMESH_subMesh *aSubMesh0 = pMesh->GetSubMeshContaining(aFxy0);
461   SMESHDS_SubMesh *aSM0=aSubMesh0->GetSubMeshDS();
462   //
463   itf=aSM0->GetElements();
464   while(itf->more()) {
465     const SMDS_MeshElement* pE0=itf->next();
466     //
467     int nbFaceNodes = pE0->NbNodes();
468     if ( aN.size() < nbFaceNodes * 2 )
469       aN.resize( nbFaceNodes * 2 );
470     //
471     k=0;
472     aItNodes=pE0->nodesIterator();
473     while (aItNodes->more()) {
474       const SMDS_MeshElement* pNode=aItNodes->next();
475       aID0=pNode->GetID();
476       aJ[k]=GetIndexOnLayer(aID0);
477       if (myErrorStatus) {
478         MESSAGE("StdMeshers_Penta_3D::MakeVolumeMesh");
479         return;
480       }
481       //
482       ++k;
483     }
484     //
485     for (i=0; i<ik; ++i){
486       i1=i;
487       i2=i+1;
488       for(j=0; j<nbFaceNodes; ++j) {
489         ij=i1*myJSize+aJ[j];
490         const StdMeshers_TNode& aTN1=myTNodes[ij];
491         const SMDS_MeshNode* aN1=aTN1.Node();
492         aN[j]=aN1;
493         //
494         ij=i2*myJSize+aJ[j];
495         const StdMeshers_TNode& aTN2=myTNodes[ij];
496         const SMDS_MeshNode* aN2=aTN2.Node();
497         aN[j+nbFaceNodes]=aN2;
498       }
499       //
500       SMDS_MeshVolume* aV = 0;
501       switch ( nbFaceNodes ) {
502       case 3:
503         aV = meshDS->AddVolume(aN[0], aN[1], aN[2],
504                                aN[3], aN[4], aN[5]);
505         break;
506       case 4:
507         aV = meshDS->AddVolume(aN[0], aN[1], aN[2], aN[3],
508                                aN[4], aN[5], aN[6], aN[7]);
509         break;
510       default:
511         continue;
512       }
513       meshDS->SetMeshElementOnShape(aV, aShell);
514     }
515   }
516 }
517
518 //=======================================================================
519 //function : MakeMeshOnFxy1
520 //purpose  : 
521 //=======================================================================
522 void StdMeshers_Penta_3D::MakeMeshOnFxy1()
523 {
524   myErrorStatus=0;
525   //
526   int aID0, aJ, aLevel, ij, aNbNodes, k;
527   //
528   SMDS_NodeIteratorPtr itn;
529   SMDS_ElemIteratorPtr itf, aItNodes;
530   SMDSAbs_ElementType aElementType;
531   //
532   const TopoDS_Face& aFxy0=
533     TopoDS::Face(myBlock.Shape(SMESH_Block::ID_Fxy0));
534   const TopoDS_Face& aFxy1=
535     TopoDS::Face(myBlock.Shape(SMESH_Block::ID_Fxy1));
536   //
537   SMESH_Mesh* pMesh=GetMesh();
538   SMESHDS_Mesh * meshDS = pMesh->GetMeshDS();
539   //
540   SMESH_subMesh *aSubMesh0 = pMesh->GetSubMeshContaining(aFxy0);
541   SMESHDS_SubMesh *aSM0=aSubMesh0->GetSubMeshDS();
542   //
543   // set nodes on aFxy1
544   aLevel=myISize-1;
545   itn=aSM0->GetNodes();
546   aNbNodes=aSM0->NbNodes();
547   //printf("** aNbNodes=%d\n", aNbNodes);
548   while(itn->more()) {
549     const SMDS_MeshNode* aN0=itn->next();
550     aID0=aN0->GetID();
551     aJ=GetIndexOnLayer(aID0);
552     if (myErrorStatus) {
553       MESSAGE("StdMeshers_Penta_3D::MakeMeshOnFxy1() ");
554       return;
555     }
556     //
557     ij=aLevel*myJSize+aJ;
558     const StdMeshers_TNode& aTN1=myTNodes[ij];
559     SMDS_MeshNode* aN1=(SMDS_MeshNode*)aTN1.Node();
560     //
561     meshDS->SetNodeOnFace(aN1, aFxy1);
562   }
563   //
564   // set elements on aFxy1
565   vector<const SMDS_MeshNode*> aNodes1;
566   //
567   itf=aSM0->GetElements();
568   while(itf->more()) {
569     const SMDS_MeshElement * pE0=itf->next();
570     aElementType=pE0->GetType();
571     if (!aElementType==SMDSAbs_Face) {
572       continue;
573     }
574     aNbNodes=pE0->NbNodes();
575 //     if (aNbNodes!=3) {
576 //       continue;
577 //     }
578     if ( aNodes1.size() < aNbNodes )
579       aNodes1.resize( aNbNodes );
580     //
581     k=aNbNodes-1; // reverse a face
582     aItNodes=pE0->nodesIterator();
583     while (aItNodes->more()) {
584       const SMDS_MeshElement* pNode=aItNodes->next();
585       aID0=pNode->GetID();
586       aJ=GetIndexOnLayer(aID0);
587       if (myErrorStatus) {
588         MESSAGE("StdMeshers_Penta_3D::MakeMeshOnFxy1() ");
589         return;
590       }
591       //
592       ij=aLevel*myJSize+aJ;
593       const StdMeshers_TNode& aTN1=myTNodes[ij];
594       const SMDS_MeshNode* aN1=aTN1.Node();
595       aNodes1[k]=aN1;
596       --k;
597     }
598     SMDS_MeshFace * face = 0;
599     switch ( aNbNodes ) {
600     case 3:
601       face = meshDS->AddFace(aNodes1[0], aNodes1[1], aNodes1[2]);
602       break;
603     case 4:
604       face = meshDS->AddFace(aNodes1[0], aNodes1[1], aNodes1[2], aNodes1[3]);
605       break;
606     default:
607       continue;
608     }
609     meshDS->SetMeshElementOnShape(face, aFxy1);
610   }
611 }
612 //=======================================================================
613 //function : ClearMeshOnFxy1
614 //purpose  : 
615 //=======================================================================
616 void StdMeshers_Penta_3D::ClearMeshOnFxy1()
617 {
618   myErrorStatus=0;
619   //
620   SMESH_subMesh* aSubMesh;
621   SMESH_Mesh* pMesh=GetMesh();
622   //
623   const TopoDS_Shape& aFxy1=myBlock.Shape(SMESH_Block::ID_Fxy1);
624   aSubMesh = pMesh->GetSubMeshContaining(aFxy1);
625   if (aSubMesh)
626     aSubMesh->ComputeStateEngine( SMESH_subMesh::CLEAN );
627 }
628
629 //=======================================================================
630 //function : GetIndexOnLayer
631 //purpose  : 
632 //=======================================================================
633 int StdMeshers_Penta_3D::GetIndexOnLayer(const int aID)
634 {
635   myErrorStatus=0;
636   //
637   int j=-1;
638   StdMeshers_IteratorOfDataMapOfIntegerInteger aMapIt;
639   //
640   aMapIt=myConnectingMap.find(aID);
641   if (aMapIt==myConnectingMap.end()) {
642     myErrorStatus=200;
643     return j;
644   }
645   j=(*aMapIt).second;
646   return j;
647 }
648 //=======================================================================
649 //function : MakeConnectingMap
650 //purpose  : 
651 //=======================================================================
652 void StdMeshers_Penta_3D::MakeConnectingMap()
653 {
654   int j, aBNID;
655   //
656   for (j=0; j<myJSize; ++j) {
657     const StdMeshers_TNode& aBN=myTNodes[j];
658     aBNID=aBN.BaseNodeID();
659     myConnectingMap[aBNID]=j;
660   }
661 }
662 //=======================================================================
663 //function : CreateNode
664 //purpose  : 
665 //=======================================================================
666 void StdMeshers_Penta_3D::CreateNode(const bool bIsUpperLayer,
667                                      const gp_XYZ& aParams,
668                                      StdMeshers_TNode& aTN)
669 {
670   myErrorStatus=0;
671   //
672   int iErr;
673   double aX, aY, aZ;
674   //
675   gp_Pnt aP;
676   //
677   SMDS_MeshNode* pNode=NULL; 
678   aTN.SetNode(pNode);  
679   //
680   if (bIsUpperLayer) {
681     // point on face Fxy1
682     const TopoDS_Shape& aS=myBlock.Shape(SMESH_Block::ID_Fxy1);
683     myBlock.Point(aParams, aS, aP);
684   }
685   else {
686     // point inside solid
687     myBlock.Point(aParams, aP);
688   }
689   //
690   iErr=myBlock.ErrorStatus();
691   if (iErr) {
692     myErrorStatus=12; // can not find the node point;
693     return;
694   }
695   //
696   aX=aP.X(); aY=aP.Y(); aZ=aP.Z(); 
697   //
698   SMESH_Mesh* pMesh=GetMesh();
699   SMESHDS_Mesh* pMeshDS=pMesh->GetMeshDS();
700   //
701   pNode = pMeshDS->AddNode(aX, aY, aZ);
702   aTN.SetNode(pNode);
703 }
704 //=======================================================================
705 //function : ShapeSupportID
706 //purpose  : 
707 //=======================================================================
708 void StdMeshers_Penta_3D::ShapeSupportID(const bool bIsUpperLayer,
709                                          const SMESH_Block::TShapeID aBNSSID,
710                                          SMESH_Block::TShapeID& aSSID)
711 {
712   myErrorStatus=0;
713   //
714   switch (aBNSSID) {
715     case SMESH_Block::ID_V000:
716       aSSID=(bIsUpperLayer) ?  SMESH_Block::ID_V001 : SMESH_Block::ID_E00z;
717       break;
718     case SMESH_Block::ID_V100:
719       aSSID=(bIsUpperLayer) ?  SMESH_Block::ID_V101 : SMESH_Block::ID_E10z;
720       break; 
721     case SMESH_Block::ID_V110:
722       aSSID=(bIsUpperLayer) ?  SMESH_Block::ID_V111 : SMESH_Block::ID_E11z;
723       break;
724     case SMESH_Block::ID_V010:
725       aSSID=(bIsUpperLayer) ?  SMESH_Block::ID_V011 : SMESH_Block::ID_E01z;
726       break;
727     case SMESH_Block::ID_Ex00:
728       aSSID=(bIsUpperLayer) ?  SMESH_Block::ID_Ex01 : SMESH_Block::ID_Fx0z;
729       break;
730     case SMESH_Block::ID_Ex10:
731       aSSID=(bIsUpperLayer) ?  SMESH_Block::ID_Ex11 : SMESH_Block::ID_Fx1z;
732       break; 
733     case SMESH_Block::ID_E0y0:
734       aSSID=(bIsUpperLayer) ?  SMESH_Block::ID_E0y1 : SMESH_Block::ID_F0yz;
735       break; 
736     case SMESH_Block::ID_E1y0:
737       aSSID=(bIsUpperLayer) ?  SMESH_Block::ID_E1y1 : SMESH_Block::ID_F1yz;
738       break; 
739     case SMESH_Block::ID_Fxy0:
740       aSSID=SMESH_Block::ID_NONE;//(bIsUpperLayer) ?  Shape_ID_Fxy1 : Shape_ID_NONE;
741       break;   
742     default:
743       aSSID=SMESH_Block::ID_NONE;
744       myErrorStatus=10; // Can not find supporting shape ID
745       break;
746   }
747   return;
748 }
749 //=======================================================================
750 //function : MakeBlock
751 //purpose  : 
752 //=======================================================================
753 void StdMeshers_Penta_3D::MakeBlock()
754 {
755   myErrorStatus=0;
756   //
757   bool bFound;
758   int i, j, iNbEV, iNbE, iErr, iCnt, iNbNodes, iNbF;
759   //
760   TopoDS_Vertex aV000, aV001;
761   TopoDS_Shape aFTr;
762   TopTools_IndexedDataMapOfShapeListOfShape aMVES;
763   TopTools_IndexedMapOfShape aME ,aMEV, aM;
764   TopTools_ListIteratorOfListOfShape aIt;
765   //
766   TopExp::MapShapes(myShape, TopAbs_FACE, aM);
767   //
768   // 0. Find triangulated face aFTr
769   SMDSAbs_ElementType aElementType;
770   SMESH_Mesh* pMesh=GetMesh();
771   //
772   iCnt=0;
773   iNbF=aM.Extent();
774   for (i=1; i<=iNbF; ++i) {
775     const TopoDS_Shape& aF=aM(i);
776     SMESH_subMesh *aSubMesh = pMesh->GetSubMeshContaining(aF);
777     ASSERT(aSubMesh);
778     SMESHDS_SubMesh *aSM=aSubMesh->GetSubMeshDS();
779     SMDS_ElemIteratorPtr itf=aSM->GetElements();
780     while(itf->more()) {
781       const SMDS_MeshElement * pElement=itf->next();
782       aElementType=pElement->GetType();
783       if (aElementType==SMDSAbs_Face) {
784         iNbNodes=pElement->NbNodes();
785         if (iNbNodes==3) {
786           aFTr=aF;
787           ++iCnt;
788           if (iCnt>1) {
789             MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
790             myErrorStatus=5; // more than one face has triangulation
791             return;
792           }
793           break; // next face
794         }
795       }
796     }
797   }
798   // 
799   // 1. Vetrices V00, V001;
800   //
801   TopExp::MapShapes(aFTr, TopAbs_EDGE, aME);
802   TopExp::MapShapesAndAncestors(myShape, TopAbs_VERTEX, TopAbs_EDGE, aMVES);
803   //
804   // 1.1 Base vertex V000
805   iNbE=aME.Extent();
806   if (iNbE!=4){
807     MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
808     myErrorStatus=7; // too few edges are in base face aFTr 
809     return;
810   }
811   const TopoDS_Edge& aE1=TopoDS::Edge(aME(1));
812   aV000=TopExp::FirstVertex(aE1);
813   //
814   const TopTools_ListOfShape& aLE=aMVES.FindFromKey(aV000);
815   aIt.Initialize(aLE);
816   for (; aIt.More(); aIt.Next()) {
817     const TopoDS_Shape& aEx=aIt.Value();
818     aMEV.Add(aEx);
819   }
820   iNbEV=aMEV.Extent();
821   if (iNbEV!=3){
822     MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
823     myErrorStatus=7; // too few edges meet in base vertex 
824     return;
825   }
826   //
827   // 1.2 Vertex V001
828   bFound=false;
829   for (j=1; j<=iNbEV; ++j) {
830     const TopoDS_Shape& aEx=aMEV(j);
831     if (!aME.Contains(aEx)) {
832       TopoDS_Vertex aV[2];
833       //
834       const TopoDS_Edge& aE=TopoDS::Edge(aEx);
835       TopExp::Vertices(aE, aV[0], aV[1]);
836       for (i=0; i<2; ++i) {
837         if (!aV[i].IsSame(aV000)) {
838           aV001=aV[i];
839           bFound=!bFound;
840           break;
841         }
842       }
843     }
844   }
845   //
846   if (!bFound) {
847     MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
848     myErrorStatus=8; // can not find reper V001 
849     return;
850   }
851   //DEB
852   //gp_Pnt aP000, aP001;
853   //
854   //aP000=BRep_Tool::Pnt(TopoDS::Vertex(aV000));
855   //printf("*** aP000 { %lf, %lf, %lf }\n", aP000.X(), aP000.Y(), aP000.Z());
856   //aP001=BRep_Tool::Pnt(TopoDS::Vertex(aV001));
857   //printf("*** aP001 { %lf, %lf, %lf }\n", aP001.X(), aP001.Y(), aP001.Z());
858   //DEB
859   //
860   aME.Clear();
861   TopExp::MapShapes(myShape, TopAbs_SHELL, aME);
862   iNbE=aME.Extent();
863   if (iNbE!=1) {
864     MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
865     myErrorStatus=9; // number of shells in source shape !=1 
866     return;
867   }
868   //
869   // 2. Load Block
870   const TopoDS_Shell& aShell=TopoDS::Shell(aME(1));
871   myBlock.Load(aShell, aV000, aV001);
872   iErr=myBlock.ErrorStatus();
873   if (iErr) {
874     MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
875     myErrorStatus=100; // SMESHBlock: Load operation failed
876     return;
877   }
878 }
879 //=======================================================================
880 //function : CheckData
881 //purpose  : 
882 //=======================================================================
883 void StdMeshers_Penta_3D::CheckData()
884 {
885   myErrorStatus=0;
886   //
887   int i, iNb;
888   int iNbEx[]={8, 12, 6};
889   //
890   TopAbs_ShapeEnum aST;
891   TopAbs_ShapeEnum aSTEx[]={
892     TopAbs_VERTEX, TopAbs_EDGE, TopAbs_FACE
893   }; 
894   TopTools_IndexedMapOfShape aM;
895   //
896   if (myShape.IsNull()){
897     MESSAGE("StdMeshers_Penta_3D::CheckData() ");
898     myErrorStatus=2; // null shape
899     return;
900   }
901   //
902   aST=myShape.ShapeType();
903   if (!(aST==TopAbs_SOLID || aST==TopAbs_SHELL)) {
904     MESSAGE("StdMeshers_Penta_3D::CheckData() ");
905     myErrorStatus=3; // not compatible type of shape
906     return;
907   }
908   //
909   for (i=0; i<3; ++i) {
910     aM.Clear();
911     TopExp::MapShapes(myShape, aSTEx[i], aM);
912     iNb=aM.Extent();
913     if (iNb!=iNbEx[i]){
914       MESSAGE("StdMeshers_Penta_3D::CheckData() ");
915       myErrorStatus=4; // number of subshape is not compatible
916       return;
917     }
918   }
919 }
920 //////////////////////////////////////////////////////////////////////////
921 //
922 //   StdMeshers_SMESHBlock
923 //
924 //
925 #include <TopTools_IndexedMapOfOrientedShape.hxx>
926 #include <TopoDS_Vertex.hxx>
927
928 //=======================================================================
929 //function : StdMeshers_SMESHBlock
930 //purpose  : 
931 //=======================================================================
932 StdMeshers_SMESHBlock::StdMeshers_SMESHBlock()
933 {
934   myErrorStatus=1;
935 }
936 //=======================================================================
937 //function : ErrorStatus
938 //purpose  : 
939 //=======================================================================
940 int StdMeshers_SMESHBlock::ErrorStatus() const
941 {
942   return myErrorStatus;
943 }
944 //=======================================================================
945 //function : Load
946 //purpose  : 
947 //=======================================================================
948 void StdMeshers_SMESHBlock::Load(const TopoDS_Shell& theShell)
949 {
950   
951   TopoDS_Vertex aV000, aV001;
952   //
953   Load(theShell, aV000, aV001);
954 }
955 //=======================================================================
956 //function : Load
957 //purpose  : 
958 //=======================================================================
959 void StdMeshers_SMESHBlock::Load(const TopoDS_Shell& theShell,
960                                  const TopoDS_Vertex& theV000,
961                                  const TopoDS_Vertex& theV001)
962 {
963   myErrorStatus=0;
964   //
965   myShell=theShell;
966   //
967   bool bOk;
968   //
969   myShapeIDMap.Clear();  
970   bOk=myTBlock.LoadBlockShapes(myShell, theV000, theV001, myShapeIDMap);
971   if (!bOk) {
972     myErrorStatus=2;
973     return;
974   }
975 }
976 //=======================================================================
977 //function : ComputeParameters
978 //purpose  : 
979 //=======================================================================
980 void StdMeshers_SMESHBlock::ComputeParameters(const gp_Pnt& thePnt, 
981                                               gp_XYZ& theXYZ)
982 {
983   ComputeParameters(thePnt, myShell, theXYZ);
984 }
985 //=======================================================================
986 //function : ComputeParameters
987 //purpose  : 
988 //=======================================================================
989 void StdMeshers_SMESHBlock::ComputeParameters(const gp_Pnt& thePnt,
990                                               const TopoDS_Shape& theShape,
991                                               gp_XYZ& theXYZ)
992 {
993   myErrorStatus=0;
994   //
995   int aID;
996   bool bOk;
997   //
998   aID=ShapeID(theShape);
999   if (myErrorStatus) {
1000     return;
1001   }
1002   bOk=myTBlock.ComputeParameters(thePnt, theXYZ, aID);
1003   if (!bOk) {
1004     myErrorStatus=4; // problems with computation Parameters 
1005     return;
1006   }
1007 }
1008 //=======================================================================
1009 //function : Point
1010 //purpose  : 
1011 //=======================================================================
1012  void StdMeshers_SMESHBlock::Point(const gp_XYZ& theParams,
1013                                    gp_Pnt& aP3D)
1014 {
1015   TopoDS_Shape aS;
1016   //
1017   Point(theParams, aS, aP3D);
1018 }
1019 //=======================================================================
1020 //function : Point
1021 //purpose  : 
1022 //=======================================================================
1023  void StdMeshers_SMESHBlock::Point(const gp_XYZ& theParams,
1024                                    const TopoDS_Shape& theShape,
1025                                    gp_Pnt& aP3D)
1026 {
1027   myErrorStatus=0;
1028   //
1029   int aID;
1030   bool bOk=false;
1031   gp_XYZ aXYZ(99.,99.,99.);
1032   aP3D.SetXYZ(aXYZ);
1033   //
1034   if (theShape.IsNull()) {
1035     bOk=myTBlock.ShellPoint(theParams, aXYZ);
1036   }
1037   //
1038   else {
1039     aID=ShapeID(theShape);
1040     if (myErrorStatus) {
1041       return;
1042     }
1043     //
1044     if (SMESH_Block::IsVertexID(aID)) {
1045       bOk=myTBlock.VertexPoint(aID, aXYZ);
1046     }
1047     else if (SMESH_Block::IsEdgeID(aID)) {
1048       bOk=myTBlock.EdgePoint(aID, theParams, aXYZ);
1049     }
1050     //
1051     else if (SMESH_Block::IsFaceID(aID)) {
1052       bOk=myTBlock.FacePoint(aID, theParams, aXYZ);
1053     }
1054   }
1055   if (!bOk) {
1056     myErrorStatus=4; // problems with point computation 
1057     return;
1058   }
1059   aP3D.SetXYZ(aXYZ);
1060 }
1061 //=======================================================================
1062 //function : ShapeID
1063 //purpose  : 
1064 //=======================================================================
1065 int StdMeshers_SMESHBlock::ShapeID(const TopoDS_Shape& theShape)
1066 {
1067   myErrorStatus=0;
1068   //
1069   int aID=-1;
1070   TopoDS_Shape aSF, aSR;
1071   //
1072   aSF=theShape;
1073   aSF.Orientation(TopAbs_FORWARD);
1074   aSR=theShape;
1075   aSR.Orientation(TopAbs_REVERSED);
1076   //
1077   if (myShapeIDMap.Contains(aSF)) {
1078     aID=myShapeIDMap.FindIndex(aSF);
1079     return aID;
1080   }
1081   if (myShapeIDMap.Contains(aSR)) {
1082     aID=myShapeIDMap.FindIndex(aSR);
1083     return aID;
1084   }
1085   myErrorStatus=2; // unknown shape;
1086   return aID;
1087 }
1088 //=======================================================================
1089 //function : Shape
1090 //purpose  : 
1091 //=======================================================================
1092 const TopoDS_Shape& StdMeshers_SMESHBlock::Shape(const int theID)
1093 {
1094   myErrorStatus=0;
1095   //
1096   int aNb;
1097   //
1098   aNb=myShapeIDMap.Extent();
1099   if (theID<1 || theID>aNb) {
1100     myErrorStatus=3; // ID is out of range
1101     return myEmptyShape;
1102   }
1103   //
1104   const TopoDS_Shape& aS=myShapeIDMap.FindKey(theID);
1105   return aS;
1106 }