1 // Created on: 2014-10-20
2 // Created by: Denis BOGOLEPOV
3 // Copyright (c) 2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <BRepExtrema_TriangleSet.hxx>
18 #include <BRep_Tool.hxx>
19 #include <BVH_LinearBuilder.hxx>
20 #include <Poly_Triangulation.hxx>
23 IMPLEMENT_STANDARD_RTTIEXT(BRepExtrema_TriangleSet, BVH_PrimitiveSet3d)
25 //=======================================================================
26 //function : BRepExtrema_TriangleSet
27 //purpose : Creates empty triangle set
28 //=======================================================================
29 BRepExtrema_TriangleSet::BRepExtrema_TriangleSet()
31 // Set default builder - linear BVH (LBVH)
32 myBuilder = new BVH_LinearBuilder<Standard_Real, 3> (BVH_Constants_LeafNodeSizeDefault, BVH_Constants_MaxTreeDepth);
35 //=======================================================================
36 //function : BRepExtrema_TriangleSet
37 //purpose : Creates triangle set from the given face
38 //=======================================================================
39 BRepExtrema_TriangleSet::BRepExtrema_TriangleSet (const BRepExtrema_ShapeList& theFaces)
41 // Set default builder - linear BVH (LBVH)
42 myBuilder = new BVH_LinearBuilder<Standard_Real, 3> (BVH_Constants_LeafNodeSizeDefault, BVH_Constants_MaxTreeDepth);
47 //=======================================================================
48 //function : ~BRepExtrema_TriangleSet
49 //purpose : Releases resources of triangle set
50 //=======================================================================
51 BRepExtrema_TriangleSet::~BRepExtrema_TriangleSet()
56 //=======================================================================
58 //purpose : Returns total number of triangles
59 //=======================================================================
60 Standard_Integer BRepExtrema_TriangleSet::Size() const
62 return static_cast<Standard_Integer> (myTriangles.size());
65 //=======================================================================
67 //purpose : Returns AABB of the given triangle
68 //=======================================================================
69 BVH_Box<Standard_Real, 3> BRepExtrema_TriangleSet::Box (const Standard_Integer theIndex) const
71 const BVH_Vec4i& aTriangle = myTriangles[theIndex];
73 BVH_Vec3d aMinPnt = myVertexArray[aTriangle.x()].cwiseMin (
74 myVertexArray[aTriangle.y()].cwiseMin (myVertexArray[aTriangle.z()]));
76 BVH_Vec3d aMaxPnt = myVertexArray[aTriangle.x()].cwiseMax (
77 myVertexArray[aTriangle.y()].cwiseMax (myVertexArray[aTriangle.z()]));
79 return BVH_Box<Standard_Real, 3> (aMinPnt, aMaxPnt);
82 //=======================================================================
84 //purpose : Returns centroid position along specified axis
85 //=======================================================================
86 Standard_Real BRepExtrema_TriangleSet::Center (const Standard_Integer theIndex, const Standard_Integer theAxis) const
88 const BVH_Vec4i& aTriangle = myTriangles[theIndex];
92 return (1.0 / 3.0) * (myVertexArray[aTriangle.x()].x() +
93 myVertexArray[aTriangle.y()].x() +
94 myVertexArray[aTriangle.z()].x());
96 else if (theAxis == 1)
98 return (1.0 / 3.0) * (myVertexArray[aTriangle.x()].y() +
99 myVertexArray[aTriangle.y()].y() +
100 myVertexArray[aTriangle.z()].y());
104 return (1.0 / 3.0) * (myVertexArray[aTriangle.x()].z() +
105 myVertexArray[aTriangle.y()].z() +
106 myVertexArray[aTriangle.z()].z());
110 //=======================================================================
112 //purpose : Swaps indices of two specified triangles
113 //=======================================================================
114 void BRepExtrema_TriangleSet::Swap (const Standard_Integer theIndex1, const Standard_Integer theIndex2)
116 std::swap (myTriangles[theIndex1],
117 myTriangles[theIndex2]);
119 std::swap (myTrgIdxMap (theIndex1),
120 myTrgIdxMap (theIndex2));
123 //=======================================================================
124 //function : GetFaceID
125 //purpose : Returns face ID of the given vertex
126 //=======================================================================
127 Standard_Integer BRepExtrema_TriangleSet::GetFaceID (const Standard_Integer theIndex) const
129 return myTriangles[theIndex].w();
132 //=======================================================================
133 //function : GetShapeIDOfVtx
134 //purpose : Returns shape ID of the given vertex index
135 //=======================================================================
136 Standard_Integer BRepExtrema_TriangleSet::GetShapeIDOfVtx (const Standard_Integer theIndex) const
138 return myShapeIdxOfVtxVec.Value (theIndex);
141 //=======================================================================
142 //function : GetVtxIdxInShape
143 //purpose : Returns vertex index in tringulation of the shape, which vertex belongs,
144 // with the given vtx ID in whole set
145 //=======================================================================
146 Standard_Integer BRepExtrema_TriangleSet::GetVtxIdxInShape (const Standard_Integer theIndex) const
148 Standard_Integer aShID = myShapeIdxOfVtxVec.Value (theIndex);
149 Standard_Integer aNumVertices = 0;
151 for (Standard_Integer aSIdx = 0; aSIdx < aShID; aSIdx++)
153 aNumVertices += myNumVtxInShapeVec.Value (aSIdx);
156 return theIndex - aNumVertices;
159 //=======================================================================
160 //function : GetTrgIdxInShape
161 //purpose : Returns triangle index (before swapping) in tringulation of the shape, which triangle belongs,
162 // with the given trg ID in whole set (after swapping)
163 //=======================================================================
164 Standard_Integer BRepExtrema_TriangleSet::GetTrgIdxInShape (const Standard_Integer theIndex) const
166 Standard_Integer aShID = GetFaceID (theIndex);
167 Standard_Integer aNumTriangles = 0;
169 for (Standard_Integer aSIdx = 0; aSIdx < aShID; aSIdx++)
171 aNumTriangles += myNumTrgInShapeVec.Value (aSIdx);
174 return myTrgIdxMap (theIndex) - aNumTriangles;
177 //=======================================================================
178 //function : GetVertices
179 //purpose : Returns vertices of the given triangle
180 //=======================================================================
181 void BRepExtrema_TriangleSet::GetVertices (const Standard_Integer theIndex,
182 BVH_Vec3d& theVertex1,
183 BVH_Vec3d& theVertex2,
184 BVH_Vec3d& theVertex3) const
186 BVH_Vec4i aTriangle = myTriangles[theIndex];
188 theVertex1 = myVertexArray[aTriangle.x()];
189 theVertex2 = myVertexArray[aTriangle.y()];
190 theVertex3 = myVertexArray[aTriangle.z()];
193 //=======================================================================
194 //function : GetVertices
195 //purpose : Returns vertices of the given triangle
196 //=======================================================================
197 void BRepExtrema_TriangleSet::GetVtxIndices (const Standard_Integer theIndex,
198 NCollection_Array1<Standard_Integer>& theVtxIndices) const
200 BVH_Vec4i aTriangle = myTriangles[theIndex];
202 theVtxIndices = NCollection_Array1<Standard_Integer> (0, 2);
203 theVtxIndices.SetValue (0, aTriangle.x());
204 theVtxIndices.SetValue (1, aTriangle.y());
205 theVtxIndices.SetValue (2, aTriangle.z());
208 //=======================================================================
210 //purpose : Clears triangle set data
211 //=======================================================================
212 void BRepExtrema_TriangleSet::Clear()
214 BVH_Array4i anEmptyTriangles;
215 myTriangles.swap (anEmptyTriangles);
217 BVH_Array3d anEmptyVertexArray;
218 myVertexArray.swap (anEmptyVertexArray);
221 //=======================================================================
223 //purpose : Initializes triangle set
224 //=======================================================================
225 Standard_Boolean BRepExtrema_TriangleSet::Init (const BRepExtrema_ShapeList& theShapes)
229 Standard_Boolean isOK = Standard_True;
230 for (Standard_Integer aShapeIdx = 0; aShapeIdx < theShapes.Size() && isOK; ++aShapeIdx)
232 if (theShapes (aShapeIdx).ShapeType() == TopAbs_FACE)
233 isOK = initFace (TopoDS::Face (theShapes(aShapeIdx)), aShapeIdx);
234 else if (theShapes (aShapeIdx).ShapeType() == TopAbs_EDGE)
235 isOK = initEdge (TopoDS::Edge (theShapes(aShapeIdx)), aShapeIdx);
238 Standard_Integer aNumTrg = static_cast<Standard_Integer> (myTriangles.size());
240 myTrgIdxMap.ReSize (aNumTrg);
242 for (Standard_Integer aTrgIdx = 0; aTrgIdx < aNumTrg; ++aTrgIdx)
244 myTrgIdxMap.Bind (aTrgIdx, aTrgIdx);
247 MarkDirty(); // needs BVH rebuilding
249 Standard_ASSERT_RETURN (!BVH().IsNull(),
250 "Error: Failed to build BVH for primitive set", Standard_False);
252 return Standard_True;
255 //=======================================================================
256 //function : initFace
257 //purpose : Initializes triangle set
258 //=======================================================================
259 Standard_Boolean BRepExtrema_TriangleSet::initFace (const TopoDS_Face& theFace, const Standard_Integer theIndex)
261 TopLoc_Location aLocation;
263 Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation (theFace, aLocation);
264 if (aTriangulation.IsNull())
266 return Standard_False;
269 const Standard_Integer aVertOffset =
270 static_cast<Standard_Integer> (myVertexArray.size()) - 1;
272 initNodes (aTriangulation->MapNodeArray()->ChangeArray1(), aLocation.Transformation(), theIndex);
274 for (Standard_Integer aTriIdx = 1; aTriIdx <= aTriangulation->NbTriangles(); ++aTriIdx)
276 Standard_Integer aVertex1;
277 Standard_Integer aVertex2;
278 Standard_Integer aVertex3;
280 aTriangulation->Triangle (aTriIdx).Get (aVertex1,
284 myTriangles.push_back (BVH_Vec4i (aVertex1 + aVertOffset,
285 aVertex2 + aVertOffset,
286 aVertex3 + aVertOffset,
290 myNumTrgInShapeVec.SetValue (theIndex, aTriangulation->NbTriangles());
292 return Standard_True;
295 //=======================================================================
296 //function : initEdge
297 //purpose : Initializes triangle set
298 //=======================================================================
299 Standard_Boolean BRepExtrema_TriangleSet::initEdge (const TopoDS_Edge& theEdge, const Standard_Integer theIndex)
301 TopLoc_Location aLocation;
303 Handle(Poly_Polygon3D) aPolygon = BRep_Tool::Polygon3D (theEdge, aLocation);
304 if (aPolygon.IsNull())
306 return Standard_False;
309 const Standard_Integer aVertOffset =
310 static_cast<Standard_Integer> (myVertexArray.size()) - 1;
312 initNodes (aPolygon->Nodes(), aLocation.Transformation(), theIndex);
314 for (Standard_Integer aVertIdx = 1; aVertIdx < aPolygon->NbNodes(); ++aVertIdx)
316 // segment as degenerate triangle
317 myTriangles.push_back (BVH_Vec4i (aVertIdx + aVertOffset,
318 aVertIdx + aVertOffset + 1,
319 aVertIdx + aVertOffset + 1,
322 return Standard_True;
325 //=======================================================================
326 //function : initNodes
327 //purpose : Initializes nodes
328 //=======================================================================
329 void BRepExtrema_TriangleSet::initNodes (const TColgp_Array1OfPnt& theNodes,
330 const gp_Trsf& theTrsf,
331 const Standard_Integer theIndex)
333 for (Standard_Integer aVertIdx = 1; aVertIdx <= theNodes.Size(); ++aVertIdx)
335 gp_Pnt aVertex = theNodes.Value (aVertIdx);
337 aVertex.Transform (theTrsf);
339 myVertexArray.push_back (BVH_Vec3d (aVertex.X(),
342 myShapeIdxOfVtxVec.Append (theIndex);
345 myNumVtxInShapeVec.SetValue (theIndex, theNodes.Size());