1 // Created by: Peter KURNEV
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14 
15 #ifndef _BOPAlgo_Tools_HeaderFile
16 #define _BOPAlgo_Tools_HeaderFile
17 
18 #include <Standard.hxx>
19 #include <Standard_DefineAlloc.hxx>
20 #include <Standard_Handle.hxx>
21 
22 #include <BOPDS_IndexedDataMapOfPaveBlockListOfInteger.hxx>
23 #include <BOPDS_IndexedDataMapOfPaveBlockListOfPaveBlock.hxx>
24 #include <BOPDS_PDS.hxx>
25 #include <NCollection_BaseAllocator.hxx>
26 #include <TopTools_DataMapOfShapeBox.hxx>
27 #include <TopTools_DataMapOfShapeListOfShape.hxx>
28 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
29 #include <TopTools_IndexedDataMapOfShapeReal.hxx>
30 #include <TopTools_ListOfListOfShape.hxx>
31 #include <TopTools_ListOfShape.hxx>
32 #include <TopTools_MapOfShape.hxx>
33 #include <Standard_Integer.hxx>
34 #include <Message_ProgressRange.hxx>
35 
36 class BOPDS_PaveBlock;
37 class BOPDS_CommonBlock;
38 class IntTools_Context;
39 class TopoDS_Shape;
40 
41 //! Provides tools used in the intersection part of Boolean operations
42 class BOPAlgo_Tools
43 {
44 public:
45 
46   //! Makes the chains of the connected elements from the given connexity map
47   template <class theType, class theTypeHasher>
MakeBlocks(const NCollection_IndexedDataMap<theType,NCollection_List<theType>,theTypeHasher> & theMILI,NCollection_List<NCollection_List<theType>> & theMBlocks,const Handle (NCollection_BaseAllocator)& theAllocator)48   static void MakeBlocks(const NCollection_IndexedDataMap<theType, NCollection_List<theType>, theTypeHasher>& theMILI,
49                          NCollection_List<NCollection_List<theType>>& theMBlocks,
50                          const Handle(NCollection_BaseAllocator)& theAllocator)
51   {
52     NCollection_Map<theType, theTypeHasher> aMFence;
53     Standard_Integer i, aNb = theMILI.Extent();
54     for (i = 1; i <= aNb; ++i) {
55       const theType& n = theMILI.FindKey(i);
56       if (!aMFence.Add(n))
57         continue;
58       //
59       // Start the chain
60       NCollection_List<theType>& aChain = theMBlocks.Append(NCollection_List<theType>(theAllocator));
61       aChain.Append(n);
62       // Look for connected elements
63       typename NCollection_List<theType>::Iterator aItLChain(aChain);
64       for (; aItLChain.More(); aItLChain.Next()) {
65         const theType& n1 = aItLChain.Value();
66         const NCollection_List<theType>& aLI = theMILI.FindFromKey(n1);
67         // Add connected elements into the chain
68         typename NCollection_List<theType>::Iterator aItLI(aLI);
69         for (; aItLI.More(); aItLI.Next()) {
70           const theType& n2 = aItLI.Value();
71           if (aMFence.Add(n2)) {
72             aChain.Append(n2);
73           }
74         }
75       }
76     }
77   }
78 
79   //! Fills the map with the connected entities
80   template <class theType, class theTypeHasher>
FillMap(const theType & n1,const theType & n2,NCollection_IndexedDataMap<theType,NCollection_List<theType>,theTypeHasher> & theMILI,const Handle (NCollection_BaseAllocator)& theAllocator)81   static void FillMap(const theType& n1,
82                       const theType& n2,
83                       NCollection_IndexedDataMap<theType, NCollection_List<theType>, theTypeHasher>& theMILI,
84                       const Handle(NCollection_BaseAllocator)& theAllocator)
85   {
86     NCollection_List<theType> *pList1 = theMILI.ChangeSeek(n1);
87     if (!pList1) {
88       pList1 = &theMILI(theMILI.Add(n1, NCollection_List<theType>(theAllocator)));
89     }
90     pList1->Append(n2);
91     //
92     NCollection_List<theType> *pList2 = theMILI.ChangeSeek(n2);
93     if (!pList2) {
94       pList2 = &theMILI(theMILI.Add(n2, NCollection_List<theType>(theAllocator)));
95     }
96     pList2->Append(n1);
97   }
98 
99   Standard_EXPORT static void FillMap(const Handle(BOPDS_PaveBlock)& thePB1,
100                                       const Standard_Integer theF,
101                                       BOPDS_IndexedDataMapOfPaveBlockListOfInteger& theMILI,
102                                       const Handle(NCollection_BaseAllocator)& theAllocator);
103 
104   //! Create Common Blocks from the groups of pave blocks of <theMBlocks>
105   //! connection map.
106   Standard_EXPORT static void PerformCommonBlocks(BOPDS_IndexedDataMapOfPaveBlockListOfPaveBlock& theMBlocks,
107                                                   const Handle(NCollection_BaseAllocator)& theAllocator,
108                                                   BOPDS_PDS& theDS,
109                                                   const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
110 
111   //! Create Common Blocks on faces using the PB->Faces connection map <theMBlocks>.
112   Standard_EXPORT static void PerformCommonBlocks(const BOPDS_IndexedDataMapOfPaveBlockListOfInteger& theMBlocks,
113                                                   const Handle(NCollection_BaseAllocator)& theAllocator,
114                                                   BOPDS_PDS& pDS,
115                                                   const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
116 
117   Standard_EXPORT static Standard_Real ComputeToleranceOfCB
118                                         (const Handle(BOPDS_CommonBlock)& theCB,
119                                          const BOPDS_PDS theDS,
120                                          const Handle(IntTools_Context)& theContext);
121 
122   //! Creates planar wires from the given edges.<br>
123   //! The input edges are expected to be planar. And for the performance
124   //! sake the method does not check if the edges are really planar.<br>
125   //! Thus, the result wires will also be not planar if the input edges are not planar.<br>
126   //! The edges may be not shared, but the resulting wires will be sharing the
127   //! coinciding parts and intersecting parts.<br>
128   //! The output wires may be non-manifold and contain free and multi-connected vertices.<br>
129   //! Parameters:
130   //! <theEdges> - input edges;<br>
131   //! <theWires> - output wires;<br>
132   //! <theShared> - boolean flag which defines whether the input edges are already
133   //!               shared or have to be intersected;<br>
134   //! <theAngTol> - the angular tolerance which will be used for distinguishing
135   //!               the planes in which the edges are located. Default value is
136   //!               1.e-8 which is used for intersection of planes in IntTools_FaceFace.<br>
137   //! Method returns the following error statuses:<br>
138   //! 0 - in case of success (at least one wire has been built);<br>
139   //! 1 - in case there are no edges in the given shape;<br>
140   //! 2 - sharing of the edges has failed.<br>
141   Standard_EXPORT static Standard_Integer EdgesToWires(const TopoDS_Shape& theEdges,
142                                                        TopoDS_Shape& theWires,
143                                                        const Standard_Boolean theShared = Standard_False,
144                                                        const Standard_Real theAngTol = 1.e-8);
145 
146   //! Creates planar faces from given planar wires.<br>
147   //! The method does not check if the wires are really planar.<br>
148   //! The input wires may be non-manifold but should be shared.<br>
149   //! The wires located in the same planes and included into other wires will create
150   //! holes in the faces built from outer wires.<br>
151   //! The tolerance values of the input shapes may be modified during the operation
152   //! due to projection of the edges on the planes for creation of 2D curves.<br>
153   //! Parameters:
154   //! <theWires> - the given wires;<br>
155   //! <theFaces> - the output faces;<br>
156   //! <theAngTol> - the angular tolerance for distinguishing the planes in which
157   //!               the wires are located. Default value is 1.e-8 which is used
158   //!               for intersection of planes in IntTools_FaceFace.<br>
159   //! Method returns TRUE in case of success, i.e. at least one face has been built.<br>
160   Standard_EXPORT static Standard_Boolean WiresToFaces(const TopoDS_Shape& theWires,
161                                                        TopoDS_Shape& theFaces,
162                                                        const Standard_Real theAngTol = 1.e-8);
163 
164   //! Finds chains of intersecting vertices
165   Standard_EXPORT static void IntersectVertices(const TopTools_IndexedDataMapOfShapeReal& theVertices,
166                                                 const Standard_Real theFuzzyValue,
167                                                 TopTools_ListOfListOfShape& theChains);
168 
169   //! Classifies the faces <theFaces> relatively solids <theSolids>.
170   //! The IN faces for solids are stored into output data map <theInParts>.
171   //!
172   //! The map <theSolidsIF> contains INTERNAL faces of the solids, to avoid
173   //! their additional classification.
174   //!
175   //! Firstly, it checks the intersection of bounding boxes of the shapes.
176   //! If the Box is not stored in the <theShapeBoxMap> map, it builds the box.
177   //! If the bounding boxes of solid and face are interfering the classification is performed.
178   //!
179   //! It is assumed that all faces and solids are already intersected and
180   //! do not have any geometrically coinciding parts without topological
181   //! sharing of these parts
182   Standard_EXPORT static void ClassifyFaces(const TopTools_ListOfShape& theFaces,
183                                             const TopTools_ListOfShape& theSolids,
184                                             const Standard_Boolean theRunParallel,
185                                             Handle(IntTools_Context)& theContext,
186                                             TopTools_IndexedDataMapOfShapeListOfShape& theInParts,
187                                             const TopTools_DataMapOfShapeBox& theShapeBoxMap = TopTools_DataMapOfShapeBox(),
188                                             const TopTools_DataMapOfShapeListOfShape& theSolidsIF = TopTools_DataMapOfShapeListOfShape(),
189                                             const Message_ProgressRange& theRange = Message_ProgressRange());
190 
191   //! Classifies the given parts relatively the given solids and
192   //! fills the solids with the parts classified as INTERNAL.
193   //!
194   //! @param theSolids  - The solids to put internals to
195   //! @param theParts   - The parts to classify relatively solids
196   //! @param theImages  - Possible images of the parts that has to be classified
197   //! @param theContext - cached geometrical tools to speed-up classifications
198   Standard_EXPORT static void FillInternals(const TopTools_ListOfShape& theSolids,
199                                             const TopTools_ListOfShape& theParts,
200                                             const TopTools_DataMapOfShapeListOfShape& theImages,
201                                             const Handle(IntTools_Context)& theContext);
202 
203   //! Computes the transformation needed to move the objects
204   //! to the given point to increase the quality of computations.
205   //! Returns true if the objects are located far from the given point
206   //! (relatively given criteria), false otherwise.
207   //! @param theBox1 the AABB of the first object
208   //! @param theBox2 the AABB of the second object
209   //! @param theTrsf the computed transformation
210   //! @param thePoint the Point to compute transformation to
211   //! @param theCriteria the Criteria to check whether thranformation is required
212   Standard_EXPORT static Standard_Boolean TrsfToPoint (const Bnd_Box& theBox1,
213                                                        const Bnd_Box& theBox2,
214                                                        gp_Trsf&       theTrsf,
215                                                        const gp_Pnt&  thePoint = gp_Pnt (0.0, 0.0, 0.0),
216                                                        const Standard_Real theCriteria = 1.e+5);
217 };
218 
219 #endif // _BOPAlgo_Tools_HeaderFile
220