0031642: Visualization - crash in Graphic3d_Structure::SetVisual() on redisplaying...
[occt.git] / src / ShapeUpgrade / ShapeUpgrade_FaceDivideArea.cxx
1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14
15 #include <BRep_Builder.hxx>
16 #include <BRepGProp.hxx>
17 #include <GProp_GProps.hxx>
18 #include <Precision.hxx>
19 #include <ShapeBuild_ReShape.hxx>
20 #include <ShapeExtend.hxx>
21 #include <ShapeUpgrade_FaceDivideArea.hxx>
22 #include <ShapeUpgrade_SplitSurfaceArea.hxx>
23 #include <Standard_Type.hxx>
24 #include <TopExp_Explorer.hxx>
25 #include <TopoDS.hxx>
26 #include <TopoDS_Face.hxx>
27 #include <TopoDS_Shape.hxx>
28
29 IMPLEMENT_STANDARD_RTTIEXT(ShapeUpgrade_FaceDivideArea,ShapeUpgrade_FaceDivide)
30
31 //=======================================================================
32 //function : ShapeUpgrade_FaceDivideArea
33 //purpose  : 
34 //=======================================================================
35 ShapeUpgrade_FaceDivideArea::ShapeUpgrade_FaceDivideArea()
36 {
37   myMaxArea = Precision::Infinite();
38   SetPrecision(1.e-5);
39   SetSplitSurfaceTool (new ShapeUpgrade_SplitSurfaceArea);
40 }
41
42 //=======================================================================
43 //function : ShapeUpgrade_FaceDivideArea
44 //purpose  : 
45 //=======================================================================
46
47 ShapeUpgrade_FaceDivideArea::ShapeUpgrade_FaceDivideArea(const TopoDS_Face& F)
48 {
49   myMaxArea = Precision::Infinite();
50   SetPrecision(1.e-5);
51   SetSplitSurfaceTool (new ShapeUpgrade_SplitSurfaceArea);
52   Init(F);
53 }
54
55 //=======================================================================
56 //function : Perform
57 //purpose  : 
58 //=======================================================================
59
60  Standard_Boolean ShapeUpgrade_FaceDivideArea::Perform() 
61 {
62   myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
63   GProp_GProps aGprop;
64   
65   BRepGProp::SurfaceProperties(myFace,aGprop,Precision());
66   Standard_Real anArea = aGprop.Mass();
67   if((anArea - myMaxArea) < Precision::Confusion())
68     return Standard_False;
69  
70   Standard_Integer anbParts = RealToInt(ceil(anArea/myMaxArea));
71   Handle(ShapeUpgrade_SplitSurfaceArea) aSurfTool= Handle(ShapeUpgrade_SplitSurfaceArea)::
72     DownCast(GetSplitSurfaceTool ());
73   if(aSurfTool.IsNull())
74     return Standard_False;
75   aSurfTool->NbParts() = anbParts;
76   if(!ShapeUpgrade_FaceDivide::Perform())
77     return Standard_False;
78   
79   TopoDS_Shape aResult = Result();
80   if(aResult.ShapeType() == TopAbs_FACE)
81     return Standard_False;
82   Standard_Integer aStatus = myStatus;
83   TopExp_Explorer aExpF(aResult,TopAbs_FACE);
84   TopoDS_Shape aCopyRes = aResult.EmptyCopied();
85   
86   Standard_Boolean isModified = Standard_False;
87   for( ; aExpF.More() ; aExpF.Next()) {
88     TopoDS_Shape aSh = Context()->Apply(aExpF.Current());
89     TopoDS_Face aFace = TopoDS::Face(aSh);
90     Init(aFace);
91     BRep_Builder aB;
92     if(Perform()) {
93       isModified = Standard_True;
94       TopoDS_Shape aRes = Result();
95       TopExp_Explorer aExpR(aRes,TopAbs_FACE);
96       for( ; aExpR.More(); aExpR.Next())
97         aB.Add(aCopyRes,aExpR.Current());
98     }
99     else
100       aB.Add(aCopyRes,aFace);
101   }
102   if(isModified)
103   {
104     if (aCopyRes.ShapeType() == TopAbs_WIRE || aCopyRes.ShapeType() == TopAbs_SHELL)
105       aCopyRes.Closed (BRep_Tool::IsClosed (aCopyRes));
106     Context()->Replace(aResult,aCopyRes);
107   }
108   myStatus |= aStatus;  
109   myResult = Context()->Apply ( aResult );
110   return Status ( ShapeExtend_DONE ); 
111 }
112