1 // Created by: Peter KURNEV
2 // Copyright (c) 2010-2014 OPEN CASCADE SAS
3 // Copyright (c) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
4 // Copyright (c) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT,
5 //                         EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 //
7 // This file is part of Open CASCADE Technology software library.
8 //
9 // This library is free software; you can redistribute it and/or modify it under
10 // the terms of the GNU Lesser General Public License version 2.1 as published
11 // by the Free Software Foundation, with special exception defined in the file
12 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
13 // distribution for complete text of the license and disclaimer of any warranty.
14 //
15 // Alternatively, this file may be used under the terms of Open CASCADE
16 // commercial license or contractual agreement.
17 
18 #ifndef _BOPAlgo_Builder_HeaderFile
19 #define _BOPAlgo_Builder_HeaderFile
20 
21 #include <Standard.hxx>
22 #include <Standard_DefineAlloc.hxx>
23 #include <Standard_Handle.hxx>
24 
25 #include <BOPAlgo_PPaveFiller.hxx>
26 #include <BOPAlgo_BuilderShape.hxx>
27 #include <BOPAlgo_GlueEnum.hxx>
28 #include <BOPAlgo_Operation.hxx>
29 #include <BOPDS_PDS.hxx>
30 #include <NCollection_BaseAllocator.hxx>
31 #include <Standard_Integer.hxx>
32 #include <Standard_Real.hxx>
33 #include <TopTools_DataMapOfShapeListOfShape.hxx>
34 #include <TopTools_DataMapOfShapeShape.hxx>
35 #include <TopTools_ListOfShape.hxx>
36 #include <TopTools_MapOfShape.hxx>
37 #include <Standard_Boolean.hxx>
38 #include <TopAbs_ShapeEnum.hxx>
39 class IntTools_Context;
40 class TopoDS_Shape;
41 
42 //!
43 //! The class is a General Fuse algorithm - base algorithm for the
44 //! algorithms in the Boolean Component. Its main purpose is to build
45 //! the split parts of the argument shapes from which the result of
46 //! the operations is combined.<br>
47 //! The result of the General Fuse algorithm itself is a compound
48 //! containing all split parts of the arguments. <br>
49 //!
50 //! Additionally to the options of the base classes, the algorithm has
51 //! the following options:<br>
52 //! - *Safe processing mode* - allows to avoid modification of the input
53 //!                            shapes during the operation (by default it is off);<br>
54 //! - *Gluing options* - allows to speed up the calculation of the intersections
55 //!                      on the special cases, in which some sub-shapes are coinciding.<br>
56 //! - *Disabling the check for inverted solids* - Disables/Enables the check of the input solids
57 //!                          for inverted status (holes in the space). The default value is TRUE,
58 //!                          i.e. the check is performed. Setting this flag to FALSE for inverted solids,
59 //!                          most likely will lead to incorrect results.
60 //!
61 //! The algorithm returns the following warnings:
62 //! - *BOPAlgo_AlertUnableToOrientTheShape* - in case the check on the orientation of the split shape
63 //!                                           to match the orientation of the original shape has failed.
64 //!
65 //! The algorithm returns the following Error statuses:
66 //! - *BOPAlgo_AlertTooFewArguments* - in case there are no enough arguments to perform the operation;
67 //! - *BOPAlgo_AlertNoFiller* - in case the intersection tool has not been created;
68 //! - *BOPAlgo_AlertIntersectionFailed* - in case the intersection of the arguments has failed;
69 //! - *BOPAlgo_AlertBuilderFailed* - in case building splits of arguments has failed with some unexpected error.
70 //!
71 class BOPAlgo_Builder  : public BOPAlgo_BuilderShape
72 {
73 public:
74 
75   DEFINE_STANDARD_ALLOC
76 
77   //! Empty constructor.
78   Standard_EXPORT BOPAlgo_Builder();
79   Standard_EXPORT virtual ~BOPAlgo_Builder();
80 
81   Standard_EXPORT BOPAlgo_Builder(const Handle(NCollection_BaseAllocator)& theAllocator);
82 
83   //! Clears the content of the algorithm.
84   Standard_EXPORT virtual void Clear() Standard_OVERRIDE;
85 
86   //! Returns the PaveFiller, algorithm for sub-shapes intersection.
PPaveFiller()87   BOPAlgo_PPaveFiller PPaveFiller()
88   {
89     return myPaveFiller;
90   }
91 
92   //! Returns the Data Structure, holder of intersection information.
PDS()93   BOPDS_PDS PDS()
94   {
95     return myDS;
96   }
97 
98   //! Returns the Context, tool for cashing heavy algorithms.
Context() const99   Handle(IntTools_Context) Context() const
100   {
101     return myContext;
102   }
103 
104 
105 public: //! @name Arguments
106 
107   //! Adds the argument to the operation.
108   Standard_EXPORT virtual void AddArgument (const TopoDS_Shape& theShape);
109 
110   //! Sets the list of arguments for the operation.
111   Standard_EXPORT virtual void SetArguments (const TopTools_ListOfShape& theLS);
112 
113   //! Returns the list of arguments.
Arguments() const114   const TopTools_ListOfShape& Arguments() const
115   {
116     return myArguments;
117   }
118 
119 public: //! @name Options
120 
121   //! Sets the flag that defines the mode of treatment.
122   //! In non-destructive mode the argument shapes are not modified. Instead
123   //! a copy of a sub-shape is created in the result if it is needed to be updated.
124   //! This flag is taken into account if internal PaveFiller is used only.
125   //! In the case of calling PerformWithFiller the corresponding flag of that PaveFiller
126   //! is in force.
SetNonDestructive(const Standard_Boolean theFlag)127   void SetNonDestructive(const Standard_Boolean theFlag)
128   {
129     myNonDestructive = theFlag;
130   }
131 
132   //! Returns the flag that defines the mode of treatment.
133   //! In non-destructive mode the argument shapes are not modified. Instead
134   //! a copy of a sub-shape is created in the result if it is needed to be updated.
NonDestructive() const135   Standard_Boolean NonDestructive() const
136   {
137     return myNonDestructive;
138   }
139 
140   //! Sets the glue option for the algorithm
SetGlue(const BOPAlgo_GlueEnum theGlue)141   void SetGlue(const BOPAlgo_GlueEnum theGlue)
142   {
143     myGlue = theGlue;
144   }
145 
146   //! Returns the glue option of the algorithm
Glue() const147   BOPAlgo_GlueEnum Glue() const
148   {
149     return myGlue;
150   }
151 
152   //! Enables/Disables the check of the input solids for inverted status
SetCheckInverted(const Standard_Boolean theCheck)153   void SetCheckInverted(const Standard_Boolean theCheck)
154   {
155     myCheckInverted = theCheck;
156   }
157 
158   //! Returns the flag defining whether the check for input solids on inverted status
159   //! should be performed or not.
CheckInverted() const160   Standard_Boolean CheckInverted() const
161   {
162     return myCheckInverted;
163   }
164 
165 
166 public: //! @name Performing the operation
167 
168   //! Performs the operation.
169   //! The intersection will be performed also.
170   Standard_EXPORT virtual void Perform(const Message_ProgressRange& theRange = Message_ProgressRange()) Standard_OVERRIDE;
171 
172   //! Performs the operation with the prepared filler.
173   //! The intersection will not be performed in this case.
174   Standard_EXPORT virtual void PerformWithFiller (const BOPAlgo_PaveFiller& theFiller, const Message_ProgressRange& theRange = Message_ProgressRange());
175 
176 
177 public: //! @name BOPs on open solids
178 
179   //! Builds the result shape according to the given states for the objects
180   //! and tools. These states can be unambiguously converted into the Boolean operation type.
181   //! Thus, it performs the Boolean operation on the given groups of shapes.
182   //!
183   //! The result is built basing on the result of Builder operation (GF or any other).
184   //! The only condition for the Builder is that the splits of faces should be created
185   //! and classified relatively solids.
186   //!
187   //! The method uses classification approach for choosing the faces which will
188   //! participate in building the result shape:
189   //! - All faces from each group having the given state for the opposite group
190   //!   will be taken into result.
191   //!
192   //! Such approach shows better results (in comparison with BOPAlgo_BuilderSolid approach)
193   //! when working with open solids. However, the result may not be always
194   //! correct on such data (at least, not as expected) as the correct classification
195   //! of the faces relatively open solids is not always possible and may vary
196   //! depending on the chosen classification point on the face.
197   //!
198   //! History is not created for the solids in this method.
199   //!
200   //! To avoid pollution of the report of Builder algorithm, there is a possibility to pass
201   //! the different report to collect the alerts of the method only. But, if the new report
202   //! is not given, the Builder report will be used.
203   //! So, even if Builder passed without any errors, but some error has been stored into its report
204   //! in this method, for the following calls the Builder report must be cleared.
205   //!
206   //! The method may set the following errors:
207   //! - BOPAlgo_AlertBuilderFailed - Building operation has not been performed yet or failed;
208   //! - BOPAlgo_AlertBOPNotSet - invalid BOP type is given (COMMON/FUSE/CUT/CUT21 are supported);
209   //! - BOPAlgo_AlertTooFewArguments - arguments are not given;
210   //! - BOPAlgo_AlertUnknownShape - the shape is unknown for the operation.
211   //!
212   //! Parameters:
213   //! @param theObjects     - The group of Objects for BOP;
214   //! @param theObjState    - State for objects faces to pass into result;
215   //! @param theTools       - The group of Tools for BOP;
216   //! @param theToolsState  - State for tools faces to pass into result;
217   //! @param theReport      - The alternative report to avoid pollution of the main one.
218   Standard_EXPORT virtual void BuildBOP(const TopTools_ListOfShape&  theObjects,
219                                         const TopAbs_State           theObjState,
220                                         const TopTools_ListOfShape&  theTools,
221                                         const TopAbs_State           theToolsState,
222                                         const Message_ProgressRange& theRange,
223                                         Handle(Message_Report)       theReport = NULL);
224 
225   //! Builds the result of Boolean operation of given type
226   //! basing on the result of Builder operation (GF or any other).
227   //!
228   //! The method converts the given type of operation into the states
229   //! for the objects and tools required for their face to pass into result
230   //! and performs the call to the same method, but with states instead
231   //! of operation type.
232   //!
233   //! The conversion looks as follows:
234   //! - COMMON is built from the faces of objects located IN any of the tools
235   //!          and vice versa.
236   //! - FUSE   is built from the faces OUT of all given shapes;
237   //! - CUT    is built from the faces of the objects OUT of the tools and
238   //!          faces of the tools located IN solids of the objects.
239   //!
240   //! @param theObjects   - The group of Objects for BOP;
241   //! @param theTools     - The group of Tools for BOP;
242   //! @param theOperation - The BOP type;
243   //! @param theRange     - The parameter to progressIndicator
244   //! @param theReport    - The alternative report to avoid pollution of the global one.
BuildBOP(const TopTools_ListOfShape & theObjects,const TopTools_ListOfShape & theTools,const BOPAlgo_Operation theOperation,const Message_ProgressRange & theRange,Handle (Message_Report)theReport=NULL)245   void BuildBOP(const TopTools_ListOfShape&  theObjects,
246                 const TopTools_ListOfShape&  theTools,
247                 const BOPAlgo_Operation      theOperation,
248                 const Message_ProgressRange& theRange,
249                 Handle(Message_Report)       theReport = NULL)
250   {
251     TopAbs_State anObjState, aToolsState;
252     switch (theOperation)
253     {
254       case BOPAlgo_COMMON:
255       {
256         anObjState  = TopAbs_IN;
257         aToolsState = TopAbs_IN;
258         break;
259       }
260       case BOPAlgo_FUSE:
261       {
262         anObjState  = TopAbs_OUT;
263         aToolsState = TopAbs_OUT;
264         break;
265       }
266       case BOPAlgo_CUT:
267       {
268         anObjState  = TopAbs_OUT;
269         aToolsState = TopAbs_IN;
270         break;
271       }
272       case BOPAlgo_CUT21:
273       {
274         anObjState  = TopAbs_IN;
275         aToolsState = TopAbs_OUT;
276         break;
277       }
278       default:
279       {
280         anObjState  = TopAbs_UNKNOWN;
281         aToolsState = TopAbs_UNKNOWN;
282         break;
283       }
284     }
285     BuildBOP(theObjects, anObjState, theTools, aToolsState, theRange, theReport);
286   }
287 
288 protected: //! @name History methods
289 
290   //! Prepare information for history support.
291   Standard_EXPORT void PrepareHistory(const Message_ProgressRange& theRange);
292 
293   //! Prepare history information for the input shapes taking into account possible
294   //! operation-specific modifications.
295   //! For instance, in the CellsBuilder operation, additionally to splitting input shapes
296   //! the splits of the shapes (or the shapes themselves) may be unified during removal of internal
297   //! boundaries. In this case each split should be linked to the unified shape.
298   //!
299   //! To have correct history information, the method should be redefined in each operation
300   //! where such additional modification is possible. The input shape <theS> should be the one from arguments,
301   //! and the returning list should contain all final elements to which the input shape has evolved,
302   //! including those not contained in the result shape.
303   //!
304   //! The method returns pointer to the list of modified elements.
305   //! NULL pointer means that the shape has not been modified at all.
306   //!
307   //! The General Fuse operation does not perform any other modification than splitting the input
308   //! shapes basing on their intersection information. This information is contained in myImages map.
309   //! Thus, here the method returns only splits (if any) contained in this map.
310   Standard_EXPORT virtual const TopTools_ListOfShape* LocModified(const TopoDS_Shape& theS);
311 
312   //! Returns the list of shapes generated from the shape theS.
313   //! Similarly to *LocModified* must be redefined for specific operations,
314   //! obtaining Generated elements differently.
315   Standard_EXPORT virtual const TopTools_ListOfShape& LocGenerated(const TopoDS_Shape& theS);
316 
317 public: //! @name Images/Origins
318 
319   //! Returns the map of images.
Images() const320   const TopTools_DataMapOfShapeListOfShape& Images() const
321   {
322     return myImages;
323   }
324 
325   //! Returns the map of origins.
Origins() const326   const TopTools_DataMapOfShapeListOfShape& Origins() const
327   {
328     return myOrigins;
329   }
330 
331   //! Returns the map of Same Domain (SD) shapes - coinciding shapes
332   //! from different arguments.
ShapesSD() const333   const TopTools_DataMapOfShapeShape& ShapesSD() const
334   {
335     return myShapesSD;
336   }
337 
338 protected://! @name Analyze progress of the operation
339 
340   //! List of operations to be supported by the Progress Indicator
341   enum BOPAlgo_PIOperation
342   {
343     PIOperation_TreatVertices = 0,
344     PIOperation_TreatEdges,
345     PIOperation_TreatWires,
346     PIOperation_TreatFaces,
347     PIOperation_TreatShells,
348     PIOperation_TreatSolids,
349     PIOperation_TreatCompsolids,
350     PIOperation_TreatCompounds,
351     PIOperation_FillHistory,
352     PIOperation_PostTreat,
353     PIOperation_Last
354   };
355 
356 
357   //! Auxiliary structure to get information about number of shapes
358   //! of each type participated in operation.
359   class NbShapes
360   {
361   public:
NbShapes()362     NbShapes()
363     {
364       for (Standard_Integer i = 0; i < 8; ++i)
365       {
366         myNbShapesArr[i] = 0;
367       }
368     }
369 
NbVertices() const370     Standard_Integer NbVertices()   const { return myNbShapesArr[0]; }
NbEdges() const371     Standard_Integer NbEdges()      const { return myNbShapesArr[1]; }
NbWires() const372     Standard_Integer NbWires()      const { return myNbShapesArr[2]; }
NbFaces() const373     Standard_Integer NbFaces()      const { return myNbShapesArr[3]; }
NbShells() const374     Standard_Integer NbShells()     const { return myNbShapesArr[4]; }
NbSolids() const375     Standard_Integer NbSolids()     const { return myNbShapesArr[5]; }
NbCompsolids() const376     Standard_Integer NbCompsolids() const { return myNbShapesArr[6]; }
NbCompounds() const377     Standard_Integer NbCompounds()  const { return myNbShapesArr[7]; }
378 
NbVertices()379     Standard_Integer& NbVertices()   { return myNbShapesArr[0]; }
NbEdges()380     Standard_Integer& NbEdges()      { return myNbShapesArr[1]; }
NbWires()381     Standard_Integer& NbWires()      { return myNbShapesArr[2]; }
NbFaces()382     Standard_Integer& NbFaces()      { return myNbShapesArr[3]; }
NbShells()383     Standard_Integer& NbShells()     { return myNbShapesArr[4]; }
NbSolids()384     Standard_Integer& NbSolids()     { return myNbShapesArr[5]; }
NbCompsolids()385     Standard_Integer& NbCompsolids() { return myNbShapesArr[6]; }
NbCompounds()386     Standard_Integer& NbCompounds()  { return myNbShapesArr[7]; }
387 
388   private:
389     Standard_Integer myNbShapesArr[8];
390   };
391 
392 protected:
393 
394   //! Compute number of shapes of certain type participating in operation
395   Standard_EXPORT NbShapes getNbShapes() const;
396 
397   //! Filling steps for constant operations
398   Standard_EXPORT void fillPIConstants(const Standard_Real theWhole, BOPAlgo_PISteps& theSteps) const Standard_OVERRIDE;
399 
400   //! Filling steps for all other operations
401   Standard_EXPORT void fillPISteps(BOPAlgo_PISteps& theSteps) const Standard_OVERRIDE;
402 
403 protected: //! @name Methods for building the result
404 
405   //! Performs the building of the result.
406   //! The method calls the PerformInternal1() method surrounded by a try-catch block.
407   Standard_EXPORT virtual void PerformInternal (const BOPAlgo_PaveFiller& thePF, const Message_ProgressRange& theRange);
408 
409   //! Performs the building of the result.
410   //! To build the result of any other operation
411   //! it will be necessary to override this method.
412   Standard_EXPORT virtual void PerformInternal1 (const BOPAlgo_PaveFiller& thePF, const Message_ProgressRange& theRange);
413 
414   //! Builds the result of operation.
415   //! The method is called for each of the arguments type and
416   //! adds into the result the splits of the arguments of that type.
417   Standard_EXPORT virtual void BuildResult (const TopAbs_ShapeEnum theType);
418 
419 
420 protected: //! @name Checking input arguments
421 
422   //! Checks the input data.
423   Standard_EXPORT virtual void CheckData() Standard_OVERRIDE;
424 
425   //! Checks if the intersection algorithm has Errors/Warnings.
426   Standard_EXPORT void CheckFiller();
427 
428   //! Prepares the result shape by making it empty compound.
429   Standard_EXPORT virtual void Prepare();
430 
431 
432 protected: //! @name Fill Images of VERTICES
433 
434   //! Fills the images of vertices.
435   Standard_EXPORT void FillImagesVertices(const Message_ProgressRange& theRange);
436 
437 
438 protected: //! @name Fill Images of EDGES
439 
440   //! Fills the images of edges.
441   Standard_EXPORT void FillImagesEdges(const Message_ProgressRange& theRange);
442 
443 
444 protected: //! @name Fill Images of CONTAINERS
445 
446   //! Fills the images of containers (WIRES/SHELLS/COMPSOLID).
447   Standard_EXPORT void FillImagesContainers (const TopAbs_ShapeEnum theType, const Message_ProgressRange& theRange);
448 
449   //! Builds the image of the given container using the splits
450   //! of its sub-shapes.
451   Standard_EXPORT void FillImagesContainer (const TopoDS_Shape& theS, const TopAbs_ShapeEnum theType);
452 
453 
454 protected: //! @name Fill Images of FACES
455 
456   //! Fills the images of faces.
457   //! The method consists of three steps:
458   //! 1. Build the splits of faces;
459   //! 2. Find SD faces;
460   //! 3. Add internal vertices (if any) to faces.
461   Standard_EXPORT void FillImagesFaces(const Message_ProgressRange& theRange);
462 
463   //! Builds the splits of faces using the information from the
464   //! intersection stage stored in Data Structure.
465   Standard_EXPORT virtual void BuildSplitFaces(const Message_ProgressRange& theRange);
466 
467   //! Looks for the same domain faces among the splits of the faces.
468   //! Updates the map of images with SD faces.
469   Standard_EXPORT void FillSameDomainFaces(const Message_ProgressRange& theRange);
470 
471   //! Classifies the alone vertices on faces relatively its splits
472   //! and adds them as INTERNAL into the splits.
473   Standard_EXPORT void FillInternalVertices(const Message_ProgressRange& theRange);
474 
475 
476 protected: //! @name Fill Images of SOLIDS
477 
478   //! Fills the images of solids.
479   //! The method consists of four steps:
480   //! 1. Build the draft solid - just rebuild the solid using the splits of faces;
481   //! 2. Find faces from other arguments located inside the solids;
482   //! 3. Build splits of solid using the inside faces;
483   //! 4. Fill internal shapes for the splits (Wires and vertices).
484   Standard_EXPORT void FillImagesSolids(const Message_ProgressRange& theRange);
485 
486   //! Builds the draft solid by rebuilding the shells of the solid
487   //! with the splits of faces.
488   Standard_EXPORT void BuildDraftSolid (const TopoDS_Shape& theSolid,
489                                         TopoDS_Shape& theDraftSolid,
490                                         TopTools_ListOfShape& theLIF);
491 
492   //! Finds faces located inside each solid.
493   Standard_EXPORT virtual void FillIn3DParts(TopTools_DataMapOfShapeShape& theDraftSolids,
494                                              const Message_ProgressRange& theRange);
495 
496   //! Builds the splits of the solids using their draft versions
497   //! and faces located inside.
498   Standard_EXPORT void BuildSplitSolids(TopTools_DataMapOfShapeShape& theDraftSolids,
499                                         const Message_ProgressRange& theRange);
500 
501   //! Classifies the vertices and edges from the arguments relatively
502   //! splits of solids and makes them INTERNAL for solids.
503   Standard_EXPORT void FillInternalShapes(const Message_ProgressRange& theRange);
504 
505 
506 protected: //! @name Fill Images of COMPOUNDS
507 
508   //! Fills the images of compounds.
509   Standard_EXPORT void FillImagesCompounds(const Message_ProgressRange& theRange);
510 
511   //! Builds the image of the given compound.
512   Standard_EXPORT void FillImagesCompound (const TopoDS_Shape& theS,
513                                            TopTools_MapOfShape& theMF);
514 
515 protected: //! @name Post treatment
516 
517   //! Post treatment of the result of the operation.
518   //! The method checks validity of the sub-shapes of the result
519   //! and updates the tolerances to make them valid.
520   Standard_EXPORT virtual void PostTreat(const Message_ProgressRange& theRange);
521 
522 protected: //! @name Fields
523 
524   TopTools_ListOfShape myArguments;             //!< Arguments of the operation
525   TopTools_MapOfShape myMapFence;               //!< Fence map providing the uniqueness of the shapes in the list of arguments
526   BOPAlgo_PPaveFiller myPaveFiller;             //!< Pave Filler - algorithm for sub-shapes intersection
527   BOPDS_PDS myDS;                               //!< Data Structure - holder of intersection information
528   Handle(IntTools_Context) myContext;           //!< Context - tool for cashing heavy algorithms such as Projectors and Classifiers
529   Standard_Integer myEntryPoint;                //!< EntryPoint - controls the deletion of the PaveFiller, which could live longer than the Builder
530   TopTools_DataMapOfShapeListOfShape myImages;  //!< Images - map of Images of the sub-shapes of arguments
531   TopTools_DataMapOfShapeShape myShapesSD;      //!< ShapesSD - map of SD Shapes
532   TopTools_DataMapOfShapeListOfShape myOrigins; //!< Origins - map of Origins, back map of Images
533   TopTools_DataMapOfShapeListOfShape myInParts; //!< InParts - map of own and acquired IN faces of the arguments solids
534   Standard_Boolean myNonDestructive;            //!< Safe processing option allows avoiding modification of the input shapes
535   BOPAlgo_GlueEnum myGlue;                      //!< Gluing option allows speeding up the intersection of the input shapes
536   Standard_Boolean myCheckInverted;             //!< Check inverted option allows disabling the check of input solids on inverted status
537 
538 };
539 
540 #endif // _BOPAlgo_Builder_HeaderFile
541