1 // File: ShapeUpgrade_ClosedFaceDivide.cxx
2 // Created: Thu Jul 22 16:11:23 1999
3 // Author: data exchange team
7 #include <ShapeUpgrade_ClosedFaceDivide.ixx>
8 #include <Precision.hxx>
9 #include <ShapeExtend.hxx>
11 #include <TopoDS_Iterator.hxx>
12 #include <TopoDS_Wire.hxx>
13 #include <ShapeExtend_WireData.hxx>
14 #include <TopoDS_Edge.hxx>
15 #include <ShapeAnalysis_Edge.hxx>
16 #include <Geom2d_Curve.hxx>
17 #include <ShapeAnalysis_Curve.hxx>
18 #include <Bnd_Box2d.hxx>
19 #include <TColStd_HSequenceOfReal.hxx>
20 #include <BRep_Tool.hxx>
21 #include <ShapeUpgrade_SplitSurface.hxx>
22 #include <ShapeExtend_CompositeSurface.hxx>
23 #include <ShapeFix_ComposeShell.hxx>
24 #include <TopExp_Explorer.hxx>
25 #include <ShapeAnalysis_Surface.hxx>
26 #include <ShapeAnalysis.hxx>
27 #include <Geom_RectangularTrimmedSurface.hxx>
28 #include <ShapeBuild_ReShape.hxx>
29 #include <ShapeAnalysis.hxx>
31 //=======================================================================
32 //function : ShapeUpgrade_ClosedFaceDivide
34 //=======================================================================
36 ShapeUpgrade_ClosedFaceDivide::ShapeUpgrade_ClosedFaceDivide():
37 ShapeUpgrade_FaceDivide()
42 //=======================================================================
43 //function : ShapeUpgrade_ClosedFaceDivide
45 //=======================================================================
47 ShapeUpgrade_ClosedFaceDivide::ShapeUpgrade_ClosedFaceDivide(const TopoDS_Face& F):
48 ShapeUpgrade_FaceDivide(F)
53 //=======================================================================
54 //function : SplitSurface
56 //=======================================================================
58 Standard_Boolean ShapeUpgrade_ClosedFaceDivide::SplitSurface()
60 Handle(ShapeUpgrade_SplitSurface) SplitSurf = GetSplitSurfaceTool();
61 if ( SplitSurf.IsNull() ) return Standard_False;
63 if ( myResult.IsNull() || myResult.ShapeType() != TopAbs_FACE ) {
64 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL3 );
65 return Standard_False;
67 TopoDS_Face face = TopoDS::Face ( myResult );
69 Standard_Real Uf,Ul,Vf,Vl;
70 ShapeAnalysis::GetFaceUVBounds ( myFace, Uf, Ul, Vf, Vl );
71 // 01.10.99 pdn Porting on DEC
72 if( ::Precision::IsInfinite(Uf) || ::Precision::IsInfinite(Ul) ||
73 ::Precision::IsInfinite(Vf) || ::Precision::IsInfinite(Vl) )
74 return Standard_False;
77 Handle(Geom_Surface) surf;
78 surf = BRep_Tool::Surface ( face, L );
80 Standard_Boolean isUSplit = Standard_False;
81 Standard_Boolean doSplit = Standard_False;
82 Handle(TColStd_HSequenceOfReal) split = new TColStd_HSequenceOfReal;
84 for(TopoDS_Iterator iter(face); iter.More()&&!doSplit; iter.Next()) {
85 if(iter.Value().ShapeType() != TopAbs_WIRE)
87 TopoDS_Wire wire = TopoDS::Wire(iter.Value());
88 Handle(ShapeExtend_WireData) sewd = new ShapeExtend_WireData(wire);
89 for(Standard_Integer i = 1; i <= sewd->NbEdges()&&!doSplit; i++)
91 doSplit = Standard_True;
92 TopoDS_Edge edge = sewd->Edge(i);
93 ShapeAnalysis_Edge sae;
94 Handle(Geom2d_Curve) c1, c2;
95 Standard_Real f1,f2,l1,l2;
96 if(!sae.PCurve(edge,face,c1,f1,l1,Standard_False))
99 TopoDS_Shape tmpE = edge.Reversed();
100 if(!sae.PCurve(TopoDS::Edge(tmpE),face,c2,f2,l2,Standard_False))
104 ShapeAnalysis_Curve sac;
106 sac.FillBndBox ( c1, f1, l1, 20, Standard_True, B1 );
107 sac.FillBndBox ( c2, f2, l2, 20, Standard_True, B2 );
108 Standard_Real x1min,y1min,x1max,y1max;
109 Standard_Real x2min,y2min,x2max,y2max;
110 B1.Get(x1min,y1min,x1max,y1max);
111 B2.Get(x2min,y2min,x2max,y2max);
112 Standard_Real xf,xl,yf,yl;
128 Standard_Real dU = xl - xf;
129 Standard_Real dV = yl - yf;
131 Standard_Real step = dU/(myNbSplit+1);
132 Standard_Real val = xf+step;
133 for(Standard_Integer j = 1; j <= myNbSplit; j++, val+=step)
135 isUSplit = Standard_True;
138 Standard_Real step = dV/(myNbSplit+1);
139 Standard_Real val = yf+step;
140 for(Standard_Integer j = 1; j <= myNbSplit; j++, val+=step)
142 isUSplit = Standard_False;
148 //pdn try to define geometric closure.
149 Handle(ShapeAnalysis_Surface) sas = new ShapeAnalysis_Surface( surf );
150 Standard_Boolean uclosed = sas->IsUClosed(Precision());
151 Standard_Boolean vclosed = sas->IsVClosed(Precision());
152 Standard_Real U1, U2, V1, V2;
154 surf -> Bounds(U1, U2, V1, V2);
155 GeomAdaptor_Surface GAS ( surf );
156 Standard_Real toler = GAS.UResolution ( Precision() );
157 if((U2-U1) - (Ul-Uf) < toler ) {
158 Handle(Geom_RectangularTrimmedSurface) rts =
159 new Geom_RectangularTrimmedSurface(surf,U1,(U2+U1)/2,Standard_True);
160 Handle(ShapeAnalysis_Surface) sast = new ShapeAnalysis_Surface( rts );
161 if ( !sast->IsUClosed(Precision())) {
162 doSplit = Standard_True;
163 Standard_Real step = (Ul-Uf)/(myNbSplit+1);
164 Standard_Real val = Uf+step;
165 for(Standard_Integer i = 1; i <= myNbSplit; i++, val+=step)
167 isUSplit = Standard_True;
170 else cout << "Warning: SU_ClosedFaceDivide: Thin face, not splitted" << endl;
174 if( vclosed && !doSplit ) {
175 surf -> Bounds(U1, U2, V1, V2);
176 GeomAdaptor_Surface GAS ( surf );
177 Standard_Real toler = GAS.VResolution ( Precision() );
178 if((V2-V1) - (Vl-Vf) < toler) {
179 Handle(Geom_RectangularTrimmedSurface) rts =
180 new Geom_RectangularTrimmedSurface(surf,V1,(V2+V1)/2,Standard_False);
181 Handle(ShapeAnalysis_Surface) sast = new ShapeAnalysis_Surface( rts );
182 if ( !sast->IsVClosed(Precision())) {
183 doSplit = Standard_True;
184 Standard_Real step = (Vl-Vf)/(myNbSplit+1);
185 Standard_Real val = Vf+step;
186 for(Standard_Integer i = 1; i <= myNbSplit; i++, val+=step)
188 isUSplit = Standard_False;
191 else cout << "Warning: SU_ClosedFaceDivide: Thin face, not splitted" << endl;
198 return Standard_False;
200 SplitSurf->Init ( surf, Uf, Ul, Vf, Vl );
202 SplitSurf->SetUSplitValues(split);
204 SplitSurf->SetVSplitValues(split);
206 SplitSurf->Perform(mySegmentMode);
207 if ( ! SplitSurf->Status ( ShapeExtend_DONE ) ) return Standard_False;
208 Handle(ShapeExtend_CompositeSurface) Grid = SplitSurf->ResSurfaces();
210 ShapeFix_ComposeShell CompShell;
211 CompShell.Init( Grid, L, face, Precision() );
212 CompShell.SetMaxTolerance(MaxTolerance());
213 CompShell.SetContext(Context());
215 if ( CompShell.Status ( ShapeExtend_FAIL ) ||
216 ! CompShell.Status ( ShapeExtend_DONE ) )
217 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL2 );
219 TopoDS_Shape res = CompShell.Result();
220 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 );
221 for(TopExp_Explorer exp(res, TopAbs_FACE); exp.More(); exp.Next()) {
223 TopoDS_Shape tempf = Context()->Apply(exp.Current());
224 TopoDS_Face f = TopoDS::Face(tempf);
227 Context()->Replace(f,myResult);
229 myResult = Context()->Apply(res);
230 return Standard_True;
234 //=======================================================================
235 //function : SetFaceNumber
237 //=======================================================================
239 void ShapeUpgrade_ClosedFaceDivide::SetNbSplitPoints(const Standard_Integer num)
245 //=======================================================================
246 //function : GetNbSplitPoints
248 //=======================================================================
250 Standard_Integer ShapeUpgrade_ClosedFaceDivide::GetNbSplitPoints() const