4b114473 |
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 | const TColgp_Array1OfPnt& aNodes = aTri->Nodes(); |
184 | Standard_Integer i; |
185 | if (aLoc.IsIdentity()) |
186 | { |
187 | for (i = 1; i <= aNbNodes; ++i) |
188 | { |
189 | thePolyg->SetValue(i, aNodes(aNodeInds(i))); |
190 | } |
191 | } |
192 | else |
193 | { |
194 | const gp_Trsf& aTr = aLoc.Transformation(); |
195 | for (i = 1; i <= aNbNodes; ++i) |
196 | { |
197 | thePolyg->SetValue(i, aNodes.Value(aNodeInds(i)).Transformed(aTr)); |
198 | } |
199 | } |
200 | return; |
201 | } |
202 | // |
203 | //Try to get Polygon2D on Surface |
204 | Handle(Poly_Polygon2D) aPolyg2D; |
205 | Handle(Geom_Surface) aS; |
206 | BRep_Tool::PolygonOnSurface(theE, aPolyg2D, aS, aLoc); |
207 | if (!aPolyg2D.IsNull()) |
208 | { |
209 | Standard_Integer aNbNodes = aPolyg2D->NbNodes(); |
210 | thePolyg = new TColgp_HArray1OfPnt(1, aNbNodes); |
211 | const TColgp_Array1OfPnt2d& aNodes2D = aPolyg2D->Nodes(); |
212 | Standard_Integer i; |
213 | if (aLoc.IsIdentity()) |
214 | { |
215 | for (i = 1; i <= aNbNodes; ++i) |
216 | { |
217 | const gp_Pnt2d& aP2d = aNodes2D(i); |
218 | gp_Pnt aP = aS->Value(aP2d.X(), aP2d.Y()); |
219 | thePolyg->SetValue(i, aP); |
220 | } |
221 | } |
222 | else |
223 | { |
224 | const gp_Trsf& aTr = aLoc.Transformation(); |
225 | for (i = 1; i <= aNbNodes; ++i) |
226 | { |
227 | const gp_Pnt2d& aP2d = aNodes2D(i); |
228 | gp_Pnt aP = aS->Value(aP2d.X(), aP2d.Y()); |
229 | aP.Transform(aTr); |
230 | thePolyg->SetValue(i, aP); |
231 | } |
232 | } |
233 | return; |
234 | } |
235 | |
236 | } |