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