0026118: Implement FastSewing algorithm
[occt.git] / src / BRepBuilderAPI / BRepBuilderAPI_FastSewing.hxx
1 //! Created on: 2015-04-24
2 //! Created by: NIKOLAI BUKHALOV
3 //! Copyright (c) 2015 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 #ifndef _BRepBuilderAPI_FastSewing_HeaderFile
17 #define _BRepBuilderAPI_FastSewing_HeaderFile
18
19 #include <Standard_Transient.hxx>
20 #include <BRep_Builder.hxx>
21
22 #include <NCollection_List.hxx>
23 #include <NCollection_Sequence.hxx>
24 #include <NCollection_Vector.hxx>
25 #include <NCollection_CellFilter.hxx>
26
27 #include <TopoDS_Edge.hxx>
28 #include <TopoDS_Face.hxx>
29 #include <TopoDS_Vertex.hxx>
30 #include <TopoDS_Wire.hxx>
31
32 class Handle(NCollection_IncAllocator);
33 class Handle(Geom_Surface);
34
35 //! This class performs fast sewing of surfaces (faces). It supposes
36 //! that all surfaces are finite and are naturally restricted by their bounds.
37 //! Moreover, it supposes that stitched together surfaces have the same parameterization
38 //! along common boundaries, therefore it does not perform time-consuming check for
39 //! SameParameter property of edges.
40 //!
41 //! For sewing, use this function as following:
42 //! - set tolerance value (default tolerance is 1.E-06)
43 //! - add all necessary surfaces (faces)
44 //! - check status if adding is correctly completed.
45 //! - compute -> Perform
46 //! - retrieve the error status if any
47 //! - retrieve the resulted shape
48 class BRepBuilderAPI_FastSewing : public Standard_Transient
49 {
50 public: 
51   typedef unsigned int FS_VARStatuses;
52
53   //! Enumeration of result statuses
54   //ATTENTION!!! If you add new status, please
55   //    describe it in GetStatuses() method
56   enum FS_Statuses
57   {
58     FS_OK                         = 0x00000000,
59     FS_Degenerated                = 0x00000001,
60     FS_FindVertexError            = 0x00000002,
61     FS_FindEdgeError              = 0x00000004,
62     FS_FaceWithNullSurface        = 0x00000008,
63     FS_NotNaturalBoundsFace       = 0x00000010,
64     FS_InfiniteSurface            = 0x00000020,
65     FS_EmptyInput                 = 0x00000040,
66     FS_Exception                  = 0x00000080
67   };
68
69
70   //! Creates an object with tolerance of connexity
71   Standard_EXPORT BRepBuilderAPI_FastSewing(const Standard_Real theTolerance = 1.0e-06);
72   
73   //! Adds faces of a shape
74   Standard_EXPORT Standard_Boolean Add(const TopoDS_Shape& theShape);
75
76   //! Adds a surface
77   Standard_EXPORT Standard_Boolean Add(const Handle(Geom_Surface)& theSurface);
78
79   //! Compute resulted shape
80   Standard_EXPORT void Perform (void) ;
81   
82   //! Sets tolerance
83   void SetTolerance (const Standard_Real theToler)
84   {
85     myTolerance = theToler;
86   }
87   
88   //! Returns tolerance
89   Standard_Real GetTolerance() const
90   {
91     return myTolerance;
92   }
93
94   //! Returns resulted shape
95   const TopoDS_Shape& GetResult() const 
96   {
97     return myResShape;
98   }
99   
100   //! Returns list of statuses. Print message if theOS != 0
101   Standard_EXPORT FS_VARStatuses GetStatuses(Standard_OStream* const theOS = 0);
102
103   DEFINE_STANDARD_RTTI(BRepBuilderAPI_FastSewing)
104
105 protected:
106   class NodeInspector;
107
108   Standard_EXPORT void FindVertexes(const Standard_Integer theSurfID,
109                                       NCollection_CellFilter<NodeInspector>& theCells);
110   Standard_EXPORT void FindEdges(const Standard_Integer theSurfID);
111   Standard_EXPORT void UpdateEdgeInfo(const Standard_Integer theIDPrevVertex,
112                                       const Standard_Integer theIDCurrVertex,
113                                       const Standard_Integer theFaceID,
114                                       const Standard_Integer theIDCurvOnFace);
115   Standard_EXPORT void CreateNewEdge( const Standard_Integer theIDPrevVertex,
116                                       const Standard_Integer theIDCurrVertex,
117                                       const Standard_Integer theFaceID,
118                                       const Standard_Integer theIDCurvOnFace);
119
120   Standard_EXPORT Standard_Real Compute3DRange();
121
122   //! Sets status. Returns numeric value of the status set
123   FS_VARStatuses SetStatus(FS_Statuses theStatus)
124   {
125     const FS_VARStatuses aStatusID = (FS_VARStatuses)(theStatus);
126     myStatusList |= aStatusID;
127     return aStatusID;
128   }
129
130   class FS_Edge;
131
132   // Classes FS_Vertex, FS_Face and FS_Edge keep information about
133   // relations between resulted members (e.g. which faces share this vertex? etc.)
134   
135   //! The struct corresponding to a vertex
136   struct FS_Vertex
137   {
138   public:
139     FS_Vertex(): myID(-1){};
140
141     //! Creates topological member (vertex)
142     void CreateTopologicalVertex(const Standard_Real theToler)
143     {
144       BRep_Builder aBuilder;
145       aBuilder.MakeVertex(myTopoVert, myPnt, theToler);
146     }
147     
148     //! Geometry point of this Vertex
149     gp_Pnt myPnt;
150     TopoDS_Vertex myTopoVert;
151
152     //! List of faces and edges which share this vertex
153     NCollection_List<Standard_Integer> myFaces;
154     NCollection_List<Standard_Integer> myEdges;
155
156     //! Indentifies the place of this Vertex in
157     //! BRepBuilderAPI_FastSewing::myVertexVec list
158     Standard_Integer myID;
159   };
160
161   //! The struct corresponding to an face
162   struct FS_Face
163   {
164     FS_Face(): myID(-1)
165     {
166       for (Standard_Integer i = 0; i < 4; i++)
167       {
168         myVertices[i] = -1;
169         myEdges[i] = -1;
170       }
171     };
172     //! Creates topological members (wire and face)
173     void CreateTopologicalWire(const NCollection_Vector<FS_Edge>& theEdgeVec,
174                                const Standard_Real theToler);
175     void CreateTopologicalFace();
176     
177     //! Sets vertex
178     void SetVertex(const Standard_Integer thePlaceID, const Standard_Integer theVertID)
179     {
180       Standard_RangeError_Raise_if((thePlaceID < 0) || (thePlaceID > 3),
181                                       "FS_Face::SetVertex(): OUT of Range");
182
183       myVertices[thePlaceID] = theVertID;
184     }
185
186     //! Sets edge
187     void SetEdge(const Standard_Integer thePlaceID, const Standard_Integer theEdgeID)
188     {
189       Standard_RangeError_Raise_if((thePlaceID < 0) || (thePlaceID > 3),
190                                       "FS_Face::SetEdge(): OUT of Range");
191
192       myEdges[thePlaceID] = theEdgeID;
193     }
194
195     TopoDS_Face mySrcFace;
196     TopoDS_Wire myWire;
197     TopoDS_Face myRetFace;
198
199     //! myEdges[i] number of the edge in myEdgeVec
200     //! (i==0) <-> (V=Vf); (i==1) <-> (U=Ul);
201     //! (i==2) <-> (V=Vl); (i==3) <-> (U=Uf)
202     Standard_Integer myEdges[4];
203     //! myVertices[i] is Start point of myEdges[i]
204     Standard_Integer myVertices[4];
205
206     //! Indentifies the place of this Face in
207     //! BRepBuilderAPI_FastSewing::myFaceVec list
208     Standard_Integer myID;
209   };
210
211   //! The struct corresponding to a edge
212   class FS_Edge
213   {
214   public:
215     FS_Edge(): myID(-1)
216     {
217       myVertices[0] = -1;
218       myVertices[1] = -1;
219     }
220
221     FS_Edge(const Standard_Integer theIDVert1, const Standard_Integer theIDVert2): myID(-1)
222     {
223       myVertices[0] = theIDVert1;
224       myVertices[1] = theIDVert2;
225     };
226
227     //! Creates topological member (TopoDS_Edge)
228     void CreateTopologicalEdge( const NCollection_Vector<FS_Vertex>& theVertexVec,
229                                 const NCollection_Vector<FS_Face>& theFaceVec,
230                                 const Standard_Real theTol);
231     
232     //! Sets vertex
233     void SetVertex(const Standard_Integer thePlaceID, const Standard_Integer theVertID)
234     {
235       Standard_RangeError_Raise_if((thePlaceID < 0) || (thePlaceID > 1),
236                                       "FS_Face::SetVertex(): OUT of Range");
237
238       myVertices[thePlaceID] = theVertID;
239     }
240
241     Standard_Boolean IsDegenerated() const
242     {
243       return (myVertices[0] == myVertices[1]);
244     }
245
246     //! List of faces which are shared with this edge
247     //! Value is the index of this shape in myFaceVec array
248     NCollection_Sequence<Standard_Integer> myFaces;
249
250     //! Indentifies the place of this Edge in
251     //! BRepBuilderAPI_FastSewing::myEdgeVec list
252     Standard_Integer myID;
253
254     TopoDS_Edge myTopoEdge;
255   private:
256     //! Index of the vertex in myVertexVec array   
257     Standard_Integer myVertices[2];
258   };
259
260   //! This inspector will find a node nearest to the given point
261   //! not far than on the given tolerance
262   class NodeInspector: public NCollection_CellFilter_InspectorXYZ
263   {
264   public:
265     typedef Standard_Integer Target;  
266
267     NodeInspector(const NCollection_Vector<FS_Vertex>& theVec,
268       const gp_Pnt& thePnt, const Standard_Real theTol);
269
270     Standard_EXPORT NCollection_CellFilter_Action Inspect (const Target theId);
271
272     Target GetResult()
273     {
274       return myResID;
275     }
276
277   private:
278     NodeInspector& operator = (const NodeInspector&);    
279     const NCollection_Vector<FS_Vertex>& myVecOfVertexes;
280     gp_Pnt myPoint;
281     Standard_Real mySQToler;
282     Target myResID;
283     Standard_Boolean myIsFindingEnable;
284   };
285 private: 
286   TopoDS_Shape myResShape;
287
288   // myFaceVec, myVertexVec and myEdgeVec lists are filled only once!!!!!
289
290   //! Vector of faces
291   NCollection_Vector<FS_Face> myFaceVec;
292   //! Vector of Vertices
293   NCollection_Vector<FS_Vertex> myVertexVec;
294   //! Vector of edges
295   NCollection_Vector<FS_Edge> myEdgeVec;
296
297   //! Tolerance
298   Standard_Real myTolerance;
299
300   //! Bits of computation status
301   FS_VARStatuses myStatusList;
302 };
303
304 #endif // _BRepBuilderAPI_FastSewing_HeaderFile
305
306 DEFINE_STANDARD_HANDLE(BRepBuilderAPI_FastSewing, Standard_Transient)