1 // File: ShapeUpgrade_FaceDivide.cxx
2 // Created: Mon Apr 26 17:29:46 1999
3 // Author: Andrey BETENEV
4 // <abv@doomox.nnov.matra-dtv.fr>
5 // gka 01.06.99 S4205: changing order of splitting surface/curves for converting to bezier
7 #include <ShapeUpgrade_FaceDivide.ixx>
8 #include <Precision.hxx>
9 #include <ShapeExtend.hxx>
10 #include <ShapeBuild_Edge.hxx>
11 #include <BRep_Builder.hxx>
12 #include <BRep_Tool.hxx>
14 #include <TopoDS_Edge.hxx>
15 #include <TopoDS_Vertex.hxx>
16 #include <TopoDS_Iterator.hxx>
17 #include <ShapeFix_ComposeShell.hxx>
18 #include <BRepTools.hxx>
19 #include <ShapeExtend_CompositeSurface.hxx>
20 #include <TopExp_Explorer.hxx>
21 #include <Bnd_Box2d.hxx>
22 #include <ShapeAnalysis.hxx>
23 #include <ShapeAnalysis_Edge.hxx>
24 #include <ShapeBuild_ReShape.hxx>
26 //=======================================================================
27 //function : ShapeUpgrade_FaceDivide
29 //=======================================================================
31 ShapeUpgrade_FaceDivide::ShapeUpgrade_FaceDivide():
32 ShapeUpgrade_Tool(), myStatus(0)
34 mySegmentMode = Standard_True;
35 mySplitSurfaceTool = new ShapeUpgrade_SplitSurface;
36 myWireDivideTool = new ShapeUpgrade_WireDivide;
39 //=======================================================================
40 //function : ShapeUpgrade_FaceDivide
42 //=======================================================================
44 ShapeUpgrade_FaceDivide::ShapeUpgrade_FaceDivide (const TopoDS_Face &F):
45 ShapeUpgrade_Tool(), myStatus(0)
47 mySegmentMode = Standard_True;
48 mySplitSurfaceTool = new ShapeUpgrade_SplitSurface;
49 myWireDivideTool = new ShapeUpgrade_WireDivide;
53 //=======================================================================
56 //=======================================================================
58 void ShapeUpgrade_FaceDivide::Init (const TopoDS_Face &F)
60 myResult = myFace = F;
64 //=======================================================================
65 //function : SetSurfaceSegmentMode
67 //=======================================================================
69 void ShapeUpgrade_FaceDivide::SetSurfaceSegmentMode(const Standard_Boolean Segment)
71 mySegmentMode = Segment;
75 //=======================================================================
78 //=======================================================================
80 Standard_Boolean ShapeUpgrade_FaceDivide::Perform ()
82 myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
83 if ( myFace.IsNull() ) return Standard_False;
87 return Status ( ShapeExtend_DONE );
90 //=======================================================================
91 //function : SplitSurface
93 //=======================================================================
95 Standard_Boolean ShapeUpgrade_FaceDivide::SplitSurface ()
97 Handle(ShapeUpgrade_SplitSurface) SplitSurf = GetSplitSurfaceTool();
98 if ( SplitSurf.IsNull() ) return Standard_False;
100 // myResult should be face; else return with FAIL
101 if ( myResult.IsNull() || myResult.ShapeType() != TopAbs_FACE ) {
102 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL3 );
103 return Standard_False;
105 TopoDS_Face face = TopoDS::Face ( myResult );
108 Handle(Geom_Surface) surf;
109 surf = BRep_Tool::Surface ( face, L );
111 Standard_Real Uf,Ul,Vf,Vl;
112 // BRepTools::UVBounds(myFace,Uf,Ul,Vf,Vl);
113 ShapeAnalysis::GetFaceUVBounds ( face, Uf, Ul, Vf, Vl );
114 if(Precision::IsInfinite(Uf) || Precision::IsInfinite(Ul) ||
115 Precision::IsInfinite(Vf) || Precision::IsInfinite(Vl))
116 return Standard_False;
118 SplitSurf->Init ( surf, Uf, Ul, Vf, Vl );
119 SplitSurf->Perform(mySegmentMode);
121 // If surface was neither splitted nor modified, do nothing
122 if ( ! SplitSurf->Status ( ShapeExtend_DONE ) ) return Standard_False;
124 // if surface was modified, force copying all vertices (and edges as consequence)
125 // to protect original shape from increasing tolerance after SameParameter
126 if ( SplitSurf->Status ( ShapeExtend_DONE3 ) )
127 for (TopExp_Explorer exp(face,TopAbs_VERTEX); exp.More(); exp.Next() ) {
128 if ( Context()->IsRecorded ( exp.Current() ) ) continue;
130 TopoDS_Shape emptyCopied = exp.Current().EmptyCopied();
131 TopoDS_Vertex V = TopoDS::Vertex ( emptyCopied );
132 Context()->Replace ( exp.Current(), V );
135 Handle(ShapeExtend_CompositeSurface) Grid = SplitSurf->ResSurfaces();
137 ShapeFix_ComposeShell CompShell;
138 CompShell.Init( Grid, L, face, Precision() );
139 CompShell.SetContext(Context());
140 CompShell.SetMaxTolerance(MaxTolerance());
141 Handle(ShapeUpgrade_WireDivide) SplitWire = GetWireDivideTool();
142 if ( ! SplitWire.IsNull() )
143 CompShell.SetTransferParamTool(GetWireDivideTool()->GetTransferParamTool());
145 if ( CompShell.Status ( ShapeExtend_FAIL ) ||
146 ! CompShell.Status ( ShapeExtend_DONE ) )
147 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL2 );
149 myResult = CompShell.Result();
150 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 );
152 return Standard_True;
155 //=======================================================================
156 //function : SplitCurves
158 //=======================================================================
160 Standard_Boolean ShapeUpgrade_FaceDivide::SplitCurves ()
162 Handle(ShapeUpgrade_WireDivide) SplitWire = GetWireDivideTool();
163 if ( SplitWire.IsNull() ) return Standard_False;
165 SplitWire->SetMaxTolerance(MaxTolerance());
166 for ( TopExp_Explorer explf(myResult,TopAbs_FACE); explf.More(); explf.Next()) {
167 TopoDS_Shape S = Context()->Apply ( explf.Current(), TopAbs_SHAPE);
169 // S should be face; else return with FAIL
170 if ( S.IsNull() || S.ShapeType() != TopAbs_FACE ) {
171 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL3 );
172 return Standard_False;
174 TopoDS_Face F = TopoDS::Face ( S );
176 SplitWire->SetFace ( F );
177 for ( TopoDS_Iterator wi(F,Standard_False); wi.More(); wi.Next() ) {
178 //TopoDS_Wire wire = TopoDS::Wire ( wi.Value() );
179 // modifications already defined in context are to be applied inside SplitWire
180 if(wi.Value().ShapeType() !=TopAbs_WIRE)
182 TopoDS_Wire wire = TopoDS::Wire(wi.Value());
183 SplitWire->Load ( wire );
184 SplitWire->SetContext(Context());
185 SplitWire->Perform ();
186 if ( SplitWire->Status ( ShapeExtend_FAIL ) )
187 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL1 );
188 if ( SplitWire->Status ( ShapeExtend_DONE ) ) {
189 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
190 Context()->Replace ( wire, SplitWire->Wire() );
194 myResult = Context()->Apply ( myResult );
195 return Status ( ShapeExtend_DONE );
198 //=======================================================================
201 //=======================================================================
203 TopoDS_Shape ShapeUpgrade_FaceDivide::Result () const
208 //=======================================================================
211 //=======================================================================
213 Standard_Boolean ShapeUpgrade_FaceDivide::Status (const ShapeExtend_Status status) const
215 return ShapeExtend::DecodeStatus ( myStatus, status );
218 //=======================================================================
219 //function : SetSplitSurfaceTool
221 //=======================================================================
223 void ShapeUpgrade_FaceDivide::SetSplitSurfaceTool(const Handle(ShapeUpgrade_SplitSurface)& splitSurfaceTool)
225 mySplitSurfaceTool = splitSurfaceTool;
228 //=======================================================================
229 //function : SetWireDivideTool
231 //=======================================================================
233 void ShapeUpgrade_FaceDivide::SetWireDivideTool(const Handle(ShapeUpgrade_WireDivide)& wireDivideTool)
235 myWireDivideTool = wireDivideTool;
238 //=======================================================================
239 //function : GetSplitSurfaceTool
241 //=======================================================================
243 Handle(ShapeUpgrade_SplitSurface) ShapeUpgrade_FaceDivide::GetSplitSurfaceTool () const
245 return mySplitSurfaceTool;
248 //=======================================================================
249 //function : GetWireDivideTool
251 //=======================================================================
253 Handle(ShapeUpgrade_WireDivide) ShapeUpgrade_FaceDivide::GetWireDivideTool () const
255 return myWireDivideTool;