Salome HOME
Copyright update 2021
[tools/medcoupling.git] / src / INTERP_KERNEL / OrientationInverter.cxx
1 // Copyright (C) 2007-2021  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony Geay (EDF R&D)
20
21 #include "OrientationInverter.hxx"
22 #include "InterpKernelException.hxx"
23 #include "CellModel.hxx"
24
25 #include <sstream>
26 #include <algorithm>
27
28 using namespace INTERP_KERNEL;
29
30 OrientationInverter *OrientationInverter::BuildInstanceFrom(NormalizedCellType gt)
31 {
32   switch(gt)
33     {
34     case NORM_SEG2:
35       return new OrientationInverterSEG2;
36     case NORM_SEG3:
37       return new OrientationInverterSEG3;
38     case NORM_TRI3:
39       return new OrientationInverter2DLinear(3u);
40     case NORM_QUAD4:
41       return new OrientationInverter2DLinear(4u);
42     case NORM_POLYGON:
43       return new OrientationInverterPolygon;
44     case NORM_TRI6:
45       return new OrientationInverter2DQuadratic(6u);
46     case NORM_QUAD8:
47       return new OrientationInverter2DQuadratic(8u);
48     case NORM_QPOLYG:
49       return new OrientationInverterQPolygon;
50     case NORM_TETRA4:
51       return new OrientationInverterTetra4;
52     case NORM_PYRA5:
53       return new OrientationInverterPyra5;
54     case NORM_PENTA6:
55       return new OrientationInverter3DExtrusionLinear(6u);
56     case NORM_HEXA8:
57       return new OrientationInverter3DExtrusionLinear(8u);
58     case NORM_TETRA10:
59       return new OrientationInverterTetra10;
60     case NORM_PYRA13:
61       return new OrientationInverterPyra13;
62     case NORM_PENTA15:
63       return new OrientationInverter3DExtrusionQuadratic(15u);
64     case NORM_HEXA20:
65       return new OrientationInverter3DExtrusionQuadratic(20u);
66     default:
67       {
68         const CellModel& cm(CellModel::GetCellModel(gt));
69         std::ostringstream oss; oss << "OrientationInverter::BuildInstanceFrom : Sorry no inverter for geo type " << cm.getRepr() << " !";
70         throw INTERP_KERNEL::Exception(oss.str());
71       }
72     }
73 }
74
75 void OrientationInverterChecker::check(mcIdType *beginPt, mcIdType *endPt) const
76 {
77   if(std::distance(beginPt,endPt)!=getNbNodes())
78     {
79       std::ostringstream oss; oss << "OrientationInverterChecker::check : length of nodal connectivity mismatches ! Expecting " << getNbNodes() << " having " << std::distance(beginPt,endPt) << " !";
80       throw INTERP_KERNEL::Exception(oss.str());
81     }
82 }
83
84 void OrientationInverterSEG2::operateAndShutUp(mcIdType *beginPt) const
85 {
86   std::swap(beginPt[0],beginPt[1]);
87 }
88
89 void OrientationInverterSEG3::operateAndShutUp(mcIdType *beginPt) const
90 {
91   std::swap(beginPt[0],beginPt[2]);
92 }
93
94 void OrientationInverter2DLinear::operateAndShutUp(mcIdType *beginPt) const
95 {
96   std::reverse(beginPt+1,beginPt+getNbNodes());
97 }
98
99 void OrientationInverter2DQuadratic::operateAndShutUp(mcIdType *beginPt) const
100 {
101   int nbNodes(getNbNodes());
102   std::reverse(beginPt+1,beginPt+nbNodes/2);
103   std::reverse(beginPt+nbNodes/2,beginPt+nbNodes);
104 }
105
106 void OrientationInverterPolygon::operate(mcIdType *beginPt, mcIdType *endPt) const
107 {
108   std::reverse(beginPt+1,endPt);
109 }
110
111 void OrientationInverterQPolygon::operate(mcIdType *beginPt, mcIdType *endPt) const
112 {
113   std::size_t sz(std::distance(beginPt,endPt));
114   std::reverse(beginPt+1,beginPt+sz/2);
115   std::reverse(beginPt+sz/2,endPt);
116 }
117
118 void OrientationInverterTetra4::operateAndShutUp(mcIdType *beginPt) const
119 {
120   std::swap(beginPt[1],beginPt[2]);
121 }
122
123 void OrientationInverterTetra10::operateAndShutUp(mcIdType *beginPt) const
124 {
125   std::swap(beginPt[1],beginPt[2]);
126   std::swap(beginPt[4],beginPt[6]);
127   std::swap(beginPt[8],beginPt[9]);
128 }
129
130 void OrientationInverterPyra5::operateAndShutUp(mcIdType *beginPt) const
131 {
132   std::reverse(beginPt+1,beginPt+4);
133 }
134
135 void OrientationInverterPyra13::operateAndShutUp(mcIdType *beginPt) const
136 {
137   std::reverse(beginPt+1,beginPt+4);
138   std::reverse(beginPt+5,beginPt+9);
139   std::swap(beginPt[10],beginPt[12]);
140 }
141
142 void OrientationInverter3DExtrusionLinear::operateAndShutUp(mcIdType *beginPt) const
143 {
144   int nbNodes(getNbNodes());
145   std::reverse(beginPt+1,beginPt+nbNodes/2);
146   std::reverse(beginPt+nbNodes/2+1,beginPt+nbNodes);
147 }
148
149 void OrientationInverter3DExtrusionQuadratic::operateAndShutUp(mcIdType *beginPt) const
150 {
151   int nbNodes(getNbNodes()),nbNodesLinearBase(nbNodes/5);
152   std::reverse(beginPt+1,beginPt+nbNodesLinearBase);
153   std::reverse(beginPt+nbNodesLinearBase+1,beginPt+2*nbNodesLinearBase);
154   std::reverse(beginPt+2*nbNodesLinearBase,beginPt+3*nbNodesLinearBase);
155   std::reverse(beginPt+3*nbNodesLinearBase,beginPt+4*nbNodesLinearBase);
156   std::reverse(beginPt+4*nbNodesLinearBase+1,beginPt+5*nbNodesLinearBase);
157 }