558e68ea |
1 | // Created on: 2014-10-20 |
2 | // Created by: Denis BOGOLEPOV |
3 | // Copyright (c) 2014 OPEN CASCADE SAS |
4 | // |
5 | // This file is part of Open CASCADE Technology software library. |
6 | // |
7 | // This library is free software; you can redistribute it and/or modify it under |
8 | // the terms of the GNU Lesser General Public License version 2.1 as published |
9 | // by the Free Software Foundation, with special exception defined in the file |
10 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
11 | // distribution for complete text of the license and disclaimer of any warranty. |
12 | // |
13 | // Alternatively, this file may be used under the terms of Open CASCADE |
14 | // commercial license or contractual agreement. |
15 | |
16 | #include <BRepExtrema_TriangleSet.hxx> |
17 | |
18 | #include <BRep_Tool.hxx> |
19 | #include <BRepAdaptor_Surface.hxx> |
20 | #include <BVH_LinearBuilder.hxx> |
21 | #include <Poly_Triangulation.hxx> |
22 | #include <TColgp_Array1OfPnt2d.hxx> |
23 | |
f5b72419 |
24 | IMPLEMENT_STANDARD_RTTIEXT(BRepExtrema_TriangleSet, BVH_PrimitiveSet3d) |
92efcf78 |
25 | |
558e68ea |
26 | //======================================================================= |
27 | //function : BRepExtrema_TriangleSet |
28 | //purpose : Creates empty triangle set |
29 | //======================================================================= |
30 | BRepExtrema_TriangleSet::BRepExtrema_TriangleSet() |
558e68ea |
31 | { |
32 | // Set default builder - linear BVH (LBVH) |
f5b72419 |
33 | myBuilder = new BVH_LinearBuilder<Standard_Real, 3> (BVH_Constants_LeafNodeSizeDefault, BVH_Constants_MaxTreeDepth); |
558e68ea |
34 | } |
35 | |
36 | //======================================================================= |
37 | //function : BRepExtrema_TriangleSet |
38 | //purpose : Creates triangle set from the given face |
39 | //======================================================================= |
40 | BRepExtrema_TriangleSet::BRepExtrema_TriangleSet (const BRepExtrema_ShapeList& theFaces) |
558e68ea |
41 | { |
42 | // Set default builder - linear BVH (LBVH) |
f5b72419 |
43 | myBuilder = new BVH_LinearBuilder<Standard_Real, 3> (BVH_Constants_LeafNodeSizeDefault, BVH_Constants_MaxTreeDepth); |
558e68ea |
44 | |
45 | Init (theFaces); |
46 | } |
47 | |
48 | //======================================================================= |
49 | //function : ~BRepExtrema_TriangleSet |
50 | //purpose : Releases resources of triangle set |
51 | //======================================================================= |
52 | BRepExtrema_TriangleSet::~BRepExtrema_TriangleSet() |
53 | { |
54 | // |
55 | } |
56 | |
57 | //======================================================================= |
58 | //function : Size |
59 | //purpose : Returns total number of triangles |
60 | //======================================================================= |
61 | Standard_Integer BRepExtrema_TriangleSet::Size() const |
62 | { |
63 | return static_cast<Standard_Integer> (myTriangles.size()); |
64 | } |
65 | |
66 | //======================================================================= |
67 | //function : Box |
68 | //purpose : Returns AABB of the given triangle |
69 | //======================================================================= |
70 | BVH_Box<Standard_Real, 3> BRepExtrema_TriangleSet::Box (const Standard_Integer theIndex) const |
71 | { |
72 | const BVH_Vec4i& aTriangle = myTriangles[theIndex]; |
73 | |
74 | BVH_Vec3d aMinPnt = myVertexArray[aTriangle.x()].cwiseMin ( |
75 | myVertexArray[aTriangle.y()].cwiseMin (myVertexArray[aTriangle.z()])); |
76 | |
77 | BVH_Vec3d aMaxPnt = myVertexArray[aTriangle.x()].cwiseMax ( |
78 | myVertexArray[aTriangle.y()].cwiseMax (myVertexArray[aTriangle.z()])); |
79 | |
80 | return BVH_Box<Standard_Real, 3> (aMinPnt, aMaxPnt); |
81 | } |
82 | |
83 | //======================================================================= |
84 | //function : Center |
85 | //purpose : Returns centroid position along specified axis |
86 | //======================================================================= |
87 | Standard_Real BRepExtrema_TriangleSet::Center (const Standard_Integer theIndex, const Standard_Integer theAxis) const |
88 | { |
89 | const BVH_Vec4i& aTriangle = myTriangles[theIndex]; |
90 | |
91 | if (theAxis == 0) |
92 | { |
93 | return (1.0 / 3.0) * (myVertexArray[aTriangle.x()].x() + |
94 | myVertexArray[aTriangle.y()].x() + |
95 | myVertexArray[aTriangle.z()].x()); |
96 | } |
97 | else if (theAxis == 1) |
98 | { |
99 | return (1.0 / 3.0) * (myVertexArray[aTriangle.x()].y() + |
100 | myVertexArray[aTriangle.y()].y() + |
101 | myVertexArray[aTriangle.z()].y()); |
102 | } |
103 | else |
104 | { |
105 | return (1.0 / 3.0) * (myVertexArray[aTriangle.x()].z() + |
106 | myVertexArray[aTriangle.y()].z() + |
107 | myVertexArray[aTriangle.z()].z()); |
108 | } |
109 | } |
110 | |
111 | //======================================================================= |
112 | //function : Swap |
113 | //purpose : Swaps indices of two specified triangles |
114 | //======================================================================= |
115 | void BRepExtrema_TriangleSet::Swap (const Standard_Integer theIndex1, const Standard_Integer theIndex2) |
116 | { |
117 | std::swap (myTriangles[theIndex1], |
118 | myTriangles[theIndex2]); |
119 | } |
120 | |
121 | //======================================================================= |
122 | //function : GetFaceID |
123 | //purpose : Returns face ID of the given triangle |
124 | //======================================================================= |
125 | Standard_Integer BRepExtrema_TriangleSet::GetFaceID (const Standard_Integer theIndex) const |
126 | { |
127 | return myTriangles[theIndex].w(); |
128 | } |
129 | |
130 | //======================================================================= |
131 | //function : GetVertices |
132 | //purpose : Returns vertices of the given triangle |
133 | //======================================================================= |
134 | void BRepExtrema_TriangleSet::GetVertices (const Standard_Integer theIndex, |
135 | BVH_Vec3d& theVertex1, |
136 | BVH_Vec3d& theVertex2, |
137 | BVH_Vec3d& theVertex3) const |
138 | { |
139 | BVH_Vec4i aTriangle = myTriangles[theIndex]; |
140 | |
141 | theVertex1 = myVertexArray[aTriangle.x()]; |
142 | theVertex2 = myVertexArray[aTriangle.y()]; |
143 | theVertex3 = myVertexArray[aTriangle.z()]; |
144 | } |
145 | |
146 | //======================================================================= |
147 | //function : Clear |
148 | //purpose : Clears triangle set data |
149 | //======================================================================= |
150 | void BRepExtrema_TriangleSet::Clear() |
151 | { |
152 | BVH_Array4i anEmptyTriangles; |
153 | myTriangles.swap (anEmptyTriangles); |
154 | |
155 | BVH_Array2d anEmptyVertUVArray; |
156 | myVertUVArray.swap (anEmptyVertUVArray); |
157 | |
158 | BVH_Array3d anEmptyVertexArray; |
159 | myVertexArray.swap (anEmptyVertexArray); |
160 | } |
161 | |
162 | //======================================================================= |
163 | //function : Init |
164 | //purpose : Initializes triangle set |
165 | //======================================================================= |
166 | Standard_Boolean BRepExtrema_TriangleSet::Init (const BRepExtrema_ShapeList& theFaces) |
167 | { |
168 | Clear(); |
169 | |
170 | for (Standard_Integer aFaceIdx = 0; aFaceIdx < theFaces.Size(); ++aFaceIdx) |
171 | { |
172 | TopLoc_Location aLocation; |
173 | |
174 | Handle(Poly_Triangulation) aTriangulation = |
175 | BRep_Tool::Triangulation (theFaces (aFaceIdx), aLocation); |
176 | |
177 | if (aTriangulation.IsNull()) |
178 | { |
179 | return Standard_False; |
180 | } |
181 | |
182 | BRepAdaptor_Surface aFaceAdaptor (theFaces (aFaceIdx), Standard_False); |
183 | |
184 | const Standard_Integer aVertOffset = |
185 | static_cast<Standard_Integer> (myVertexArray.size()) - 1; |
186 | |
187 | for (Standard_Integer aVertIdx = 1; aVertIdx <= aTriangulation->NbNodes(); ++aVertIdx) |
188 | { |
189 | gp_Pnt aVertex = aTriangulation->Nodes().Value (aVertIdx); |
190 | |
191 | aVertex.Transform (aLocation.Transformation()); |
192 | |
193 | myVertexArray.push_back (BVH_Vec3d (aVertex.X(), |
194 | aVertex.Y(), |
195 | aVertex.Z())); |
196 | |
197 | const Standard_Real aU = aTriangulation->UVNodes().Value (aVertIdx).X(); |
198 | const Standard_Real aV = aTriangulation->UVNodes().Value (aVertIdx).Y(); |
199 | |
200 | myVertUVArray.push_back (BVH_Vec2d (aU, aV)); |
201 | } |
202 | |
203 | for (Standard_Integer aTriIdx = 1; aTriIdx <= aTriangulation->NbTriangles(); ++aTriIdx) |
204 | { |
205 | Standard_Integer aVertex1; |
206 | Standard_Integer aVertex2; |
207 | Standard_Integer aVertex3; |
208 | |
209 | aTriangulation->Triangles().Value (aTriIdx).Get (aVertex1, |
210 | aVertex2, |
211 | aVertex3); |
212 | |
213 | myTriangles.push_back (BVH_Vec4i (aVertex1 + aVertOffset, |
214 | aVertex2 + aVertOffset, |
215 | aVertex3 + aVertOffset, |
216 | aFaceIdx)); |
217 | } |
218 | } |
219 | |
220 | MarkDirty(); // needs BVH rebuilding |
221 | |
222 | Standard_ASSERT_RETURN (!BVH().IsNull(), |
223 | "Error: Failed to build BVH for primitive set", Standard_False); |
224 | |
225 | return Standard_True; |
226 | } |
ae9a414a |
227 | |