0032133: Modeling Data - Restriction of access to internal arrays for Poly_Triangulat...
[occt.git] / src / BRepGProp / BRepGProp_MeshCinert.cxx
1 // Copyright (c) 2018 OPEN CASCADE SAS
2 // This file is part of Open CASCADE Technology software library.
3 //
4 // This library is free software; you can redistribute it and/or modify it under
5 // the terms of the GNU Lesser General Public License version 2.1 as published
6 // by the Free Software Foundation, with special exception defined in the file
7 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
8 // distribution for complete text of the license and disclaimer of any warranty.
9 //
10 // Alternatively, this file may be used under the terms of Open CASCADE
11 // commercial license or contractual agreement.
12
13
14 #include <BRepGProp_MeshCinert.hxx>
15 #include <gp_Pnt.hxx>
16 #include <math.hxx>
17 #include <TopoDS_Edge.hxx>
18 #include <Poly_Polygon3D.hxx>
19 #include <BRep_Tool.hxx>
20
21 //=======================================================================
22 //function : BRepGProp_MeshCinert
23 //purpose  : 
24 //=======================================================================
25
26 BRepGProp_MeshCinert::BRepGProp_MeshCinert()
27 {
28 }
29
30 //=======================================================================
31 //function : SetLocation
32 //purpose  : 
33 //=======================================================================
34 void BRepGProp_MeshCinert::SetLocation(const gp_Pnt& CLocation)
35 {
36   loc = CLocation;
37 }
38
39 //=======================================================================
40 //function : Perform
41 //purpose  : 
42 //=======================================================================
43 void BRepGProp_MeshCinert::Perform(const TColgp_Array1OfPnt& theNodes)
44 {
45
46   Standard_Real Ix, Iy, Iz, Ixx, Iyy, Izz, Ixy, Ixz, Iyz;
47   dim = Ix = Iy = Iz = Ixx = Iyy = Izz = Ixy = Ixz = Iyz = 0.0;
48
49   Standard_Integer Order = 2; 
50
51   Standard_Real ds;  
52   Standard_Real ur, um, u;
53   Standard_Real x, y, z; 
54   Standard_Real xloc, yloc, zloc;
55   Standard_Real Upper;
56   gp_XYZ P, D;
57
58   math_Vector GaussP (1, Order);
59   math_Vector GaussW (1, Order);
60
61   math::GaussPoints  (Order,GaussP);
62   math::GaussWeights (Order,GaussW);
63
64   Standard_Integer nIndex = 0;
65
66   for(nIndex = 1; nIndex < theNodes.Length(); nIndex++) 
67   {
68     const gp_XYZ& aP1 = theNodes(nIndex).XYZ();
69     const gp_XYZ& aP2 = theNodes(nIndex + 1).XYZ();
70     Standard_Real dimLocal, IxLocal, IyLocal, IzLocal, IxxLocal, IyyLocal, IzzLocal, IxyLocal, IxzLocal, IyzLocal;
71     dimLocal = IxLocal = IyLocal = IzLocal = IxxLocal = IyyLocal = IzzLocal = IxyLocal = IxzLocal = IyzLocal = 0.0;
72
73     loc.Coord (xloc, yloc, zloc);
74
75     Standard_Integer i;
76
77     Upper = (aP2 - aP1).Modulus();
78     if (Upper < gp::Resolution())
79     {
80       continue;
81     }
82     um = 0.5 * Upper;
83     ur =um;
84     D = (aP2 - aP1) / Upper;
85
86     for (i = 1; i <= Order; i++) {
87       u = um + ur * GaussP (i);
88       P = aP1 + u * D;
89       P.Coord (x, y, z);
90       x   -= xloc;
91       y   -= yloc;
92       z   -= zloc;
93       ds = GaussW (i);
94       dimLocal += ds; 
95       IxLocal  += x * ds;  
96       IyLocal  += y * ds;
97       IzLocal  += z * ds;
98       IxyLocal += x * y * ds;
99       IyzLocal += y * z * ds;
100       IxzLocal += x * z * ds;
101       x   *= x;      
102       y   *= y;      
103       z   *= z;      
104       IxxLocal += (y + z) * ds;
105       IyyLocal += (x + z) * ds;
106       IzzLocal += (x + y) * ds;
107     }
108
109     dimLocal *= ur;
110     IxLocal  *= ur;
111     IyLocal  *= ur;
112     IzLocal  *= ur;
113     IxxLocal *= ur;
114     IyyLocal *= ur;
115     IzzLocal *= ur;
116     IxyLocal *= ur;
117     IxzLocal *= ur;
118     IyzLocal *= ur;
119
120     dim += dimLocal;
121     Ix += IxLocal;
122     Iy += IyLocal;
123     Iz += IzLocal;
124     Ixx += IxxLocal;
125     Iyy += IyyLocal;
126     Izz += IzzLocal;
127     Ixy += IxyLocal;
128     Ixz += IxzLocal;
129     Iyz += IyzLocal;
130   }
131
132   inertia = gp_Mat (gp_XYZ (Ixx, -Ixy, -Ixz),
133     gp_XYZ (-Ixy, Iyy, -Iyz),
134     gp_XYZ (-Ixz, -Iyz, Izz));
135
136   if (Abs(dim) < gp::Resolution())
137     g = P;
138   else
139     g.SetCoord (Ix/dim, Iy/dim, Iz/dim);
140 }
141
142 //=======================================================================
143 //function : PreparePolygon
144 //purpose  : 
145 //=======================================================================
146 void BRepGProp_MeshCinert::PreparePolygon(const TopoDS_Edge& theE, 
147                                           Handle(TColgp_HArray1OfPnt)& thePolyg)
148 {
149   TopLoc_Location aLoc;
150   const Handle(Poly_Polygon3D)& aPolyg = BRep_Tool::Polygon3D(theE, aLoc);
151   if (!aPolyg.IsNull())
152   {
153     const TColgp_Array1OfPnt& aNodes = aPolyg->Nodes();
154     thePolyg = new TColgp_HArray1OfPnt(1, aNodes.Length());
155     Standard_Integer i;
156     if (aLoc.IsIdentity())
157     {
158       for (i = 1; i <= aNodes.Length(); ++i)
159       {
160         thePolyg->SetValue(i, aNodes(i));
161       }
162     }
163     else
164     {
165       const gp_Trsf& aTr = aLoc.Transformation();
166       for (i = 1; i <= aNodes.Length(); ++i)
167       {
168         thePolyg->SetValue(i, aNodes.Value(i).Transformed(aTr));
169       }
170     }
171     return;
172   }
173
174   //Try to get PolygonOnTriangulation
175   Handle(Poly_Triangulation) aTri;
176   Handle(Poly_PolygonOnTriangulation) aPOnTri;
177   BRep_Tool::PolygonOnTriangulation(theE, aPOnTri, aTri, aLoc);
178   if (!aPOnTri.IsNull())
179   {
180     Standard_Integer aNbNodes = aPOnTri->NbNodes();
181     thePolyg = new TColgp_HArray1OfPnt(1, aNbNodes);
182     const TColStd_Array1OfInteger& aNodeInds = aPOnTri->Nodes();
183     Standard_Integer i;
184     if (aLoc.IsIdentity())
185     {
186       for (i = 1; i <= aNbNodes; ++i)
187       {
188         thePolyg->SetValue (i, aTri->Node (aNodeInds (i)));
189       }
190     }
191     else
192     {
193       const gp_Trsf& aTr = aLoc.Transformation();
194       for (i = 1; i <= aNbNodes; ++i)
195       {
196         thePolyg->SetValue (i, aTri->Node (aNodeInds (i)).Transformed (aTr));
197       }
198     }
199     return;
200   }
201   //
202   //Try to get Polygon2D on Surface
203   Handle(Poly_Polygon2D) aPolyg2D;
204   Handle(Geom_Surface) aS;
205   BRep_Tool::PolygonOnSurface(theE, aPolyg2D, aS, aLoc);
206   if (!aPolyg2D.IsNull())
207   {
208     Standard_Integer aNbNodes = aPolyg2D->NbNodes();
209     thePolyg = new TColgp_HArray1OfPnt(1, aNbNodes);
210     const TColgp_Array1OfPnt2d& aNodes2D = aPolyg2D->Nodes();
211     Standard_Integer i;
212     if (aLoc.IsIdentity())
213     {
214       for (i = 1; i <= aNbNodes; ++i)
215       {
216         const gp_Pnt2d& aP2d = aNodes2D(i);
217         gp_Pnt aP = aS->Value(aP2d.X(), aP2d.Y());
218         thePolyg->SetValue(i, aP);
219       }
220     }
221     else
222     {
223       const gp_Trsf& aTr = aLoc.Transformation();
224       for (i = 1; i <= aNbNodes; ++i)
225       {
226         const gp_Pnt2d& aP2d = aNodes2D(i);
227         gp_Pnt aP = aS->Value(aP2d.X(), aP2d.Y());
228         aP.Transform(aTr);
229         thePolyg->SetValue(i, aP);
230       }
231     }
232     return;
233   }
234
235 }