b311480e |
1 | // Created on: 1999-07-22 |
2 | // Created by: data exchange team |
3 | // Copyright (c) 1999-1999 Matra Datavision |
973c2be1 |
4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
5 | // |
973c2be1 |
6 | // This file is part of Open CASCADE Technology software library. |
b311480e |
7 | // |
d5f74e42 |
8 | // This library is free software; you can redistribute it and/or modify it under |
9 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
10 | // by the Free Software Foundation, with special exception defined in the file |
11 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
12 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
13 | // |
973c2be1 |
14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. |
7fd59977 |
16 | |
17 | #include <ShapeUpgrade_ClosedFaceDivide.ixx> |
18 | #include <Precision.hxx> |
19 | #include <ShapeExtend.hxx> |
20 | #include <TopoDS.hxx> |
21 | #include <TopoDS_Iterator.hxx> |
22 | #include <TopoDS_Wire.hxx> |
23 | #include <ShapeExtend_WireData.hxx> |
24 | #include <TopoDS_Edge.hxx> |
25 | #include <ShapeAnalysis_Edge.hxx> |
26 | #include <Geom2d_Curve.hxx> |
27 | #include <ShapeAnalysis_Curve.hxx> |
28 | #include <Bnd_Box2d.hxx> |
29 | #include <TColStd_HSequenceOfReal.hxx> |
30 | #include <BRep_Tool.hxx> |
31 | #include <ShapeUpgrade_SplitSurface.hxx> |
32 | #include <ShapeExtend_CompositeSurface.hxx> |
33 | #include <ShapeFix_ComposeShell.hxx> |
34 | #include <TopExp_Explorer.hxx> |
35 | #include <ShapeAnalysis_Surface.hxx> |
36 | #include <ShapeAnalysis.hxx> |
37 | #include <Geom_RectangularTrimmedSurface.hxx> |
38 | #include <ShapeBuild_ReShape.hxx> |
39 | #include <ShapeAnalysis.hxx> |
40 | |
41 | //======================================================================= |
42 | //function : ShapeUpgrade_ClosedFaceDivide |
43 | //purpose : |
44 | //======================================================================= |
45 | |
46 | ShapeUpgrade_ClosedFaceDivide::ShapeUpgrade_ClosedFaceDivide(): |
47 | ShapeUpgrade_FaceDivide() |
48 | { |
49 | myNbSplit = 1; |
50 | } |
51 | |
52 | //======================================================================= |
53 | //function : ShapeUpgrade_ClosedFaceDivide |
54 | //purpose : |
55 | //======================================================================= |
56 | |
57 | ShapeUpgrade_ClosedFaceDivide::ShapeUpgrade_ClosedFaceDivide(const TopoDS_Face& F): |
58 | ShapeUpgrade_FaceDivide(F) |
59 | { |
60 | myNbSplit = 1; |
61 | } |
62 | |
63 | //======================================================================= |
64 | //function : SplitSurface |
65 | //purpose : |
66 | //======================================================================= |
67 | |
68 | Standard_Boolean ShapeUpgrade_ClosedFaceDivide::SplitSurface() |
69 | { |
70 | Handle(ShapeUpgrade_SplitSurface) SplitSurf = GetSplitSurfaceTool(); |
71 | if ( SplitSurf.IsNull() ) return Standard_False; |
72 | |
73 | if ( myResult.IsNull() || myResult.ShapeType() != TopAbs_FACE ) { |
74 | myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL3 ); |
75 | return Standard_False; |
76 | } |
77 | TopoDS_Face face = TopoDS::Face ( myResult ); |
78 | |
79 | Standard_Real Uf,Ul,Vf,Vl; |
80 | ShapeAnalysis::GetFaceUVBounds ( myFace, Uf, Ul, Vf, Vl ); |
81 | // 01.10.99 pdn Porting on DEC |
82 | if( ::Precision::IsInfinite(Uf) || ::Precision::IsInfinite(Ul) || |
83 | ::Precision::IsInfinite(Vf) || ::Precision::IsInfinite(Vl) ) |
84 | return Standard_False; |
85 | |
86 | TopLoc_Location L; |
87 | Handle(Geom_Surface) surf; |
88 | surf = BRep_Tool::Surface ( face, L ); |
89 | |
90 | Standard_Boolean isUSplit = Standard_False; |
91 | Standard_Boolean doSplit = Standard_False; |
92 | Handle(TColStd_HSequenceOfReal) split = new TColStd_HSequenceOfReal; |
93 | |
94 | for(TopoDS_Iterator iter(face); iter.More()&&!doSplit; iter.Next()) { |
95 | if(iter.Value().ShapeType() != TopAbs_WIRE) |
96 | continue; |
97 | TopoDS_Wire wire = TopoDS::Wire(iter.Value()); |
98 | Handle(ShapeExtend_WireData) sewd = new ShapeExtend_WireData(wire); |
99 | for(Standard_Integer i = 1; i <= sewd->NbEdges()&&!doSplit; i++) |
100 | if(sewd->IsSeam(i)) { |
101 | doSplit = Standard_True; |
102 | TopoDS_Edge edge = sewd->Edge(i); |
103 | ShapeAnalysis_Edge sae; |
104 | Handle(Geom2d_Curve) c1, c2; |
105 | Standard_Real f1,f2,l1,l2; |
106 | if(!sae.PCurve(edge,face,c1,f1,l1,Standard_False)) |
107 | continue; |
108 | //smh#8 |
109 | TopoDS_Shape tmpE = edge.Reversed(); |
110 | if(!sae.PCurve(TopoDS::Edge(tmpE),face,c2,f2,l2,Standard_False)) |
111 | continue; |
112 | if(c2==c1) continue; |
113 | // splitting |
114 | ShapeAnalysis_Curve sac; |
115 | Bnd_Box2d B1, B2; |
116 | sac.FillBndBox ( c1, f1, l1, 20, Standard_True, B1 ); |
117 | sac.FillBndBox ( c2, f2, l2, 20, Standard_True, B2 ); |
118 | Standard_Real x1min,y1min,x1max,y1max; |
119 | Standard_Real x2min,y2min,x2max,y2max; |
120 | B1.Get(x1min,y1min,x1max,y1max); |
121 | B2.Get(x2min,y2min,x2max,y2max); |
122 | Standard_Real xf,xl,yf,yl; |
123 | if(x1min < x2min) { |
124 | xf = x1max; |
125 | xl = x2min; |
126 | } else { |
127 | xf = x2max; |
128 | xl = x1min; |
129 | } |
130 | if(y1min < y2min) { |
131 | yf = y1max; |
132 | yl = y2min; |
133 | } else { |
134 | yf = y2max; |
135 | yl = y1min; |
136 | } |
137 | |
138 | Standard_Real dU = xl - xf; |
139 | Standard_Real dV = yl - yf; |
140 | if(dU > dV) { |
141 | Standard_Real step = dU/(myNbSplit+1); |
142 | Standard_Real val = xf+step; |
143 | for(Standard_Integer j = 1; j <= myNbSplit; j++, val+=step) |
144 | split->Append(val); |
145 | isUSplit = Standard_True; |
146 | } |
147 | else { |
148 | Standard_Real step = dV/(myNbSplit+1); |
149 | Standard_Real val = yf+step; |
150 | for(Standard_Integer j = 1; j <= myNbSplit; j++, val+=step) |
151 | split->Append(val); |
152 | isUSplit = Standard_False; |
153 | } |
154 | } |
155 | } |
156 | |
157 | if(!doSplit) { |
158 | //pdn try to define geometric closure. |
159 | Handle(ShapeAnalysis_Surface) sas = new ShapeAnalysis_Surface( surf ); |
160 | Standard_Boolean uclosed = sas->IsUClosed(Precision()); |
161 | Standard_Boolean vclosed = sas->IsVClosed(Precision()); |
162 | Standard_Real U1, U2, V1, V2; |
163 | if(uclosed) { |
164 | surf -> Bounds(U1, U2, V1, V2); |
165 | GeomAdaptor_Surface GAS ( surf ); |
166 | Standard_Real toler = GAS.UResolution ( Precision() ); |
167 | if((U2-U1) - (Ul-Uf) < toler ) { |
168 | Handle(Geom_RectangularTrimmedSurface) rts = |
169 | new Geom_RectangularTrimmedSurface(surf,U1,(U2+U1)/2,Standard_True); |
170 | Handle(ShapeAnalysis_Surface) sast = new ShapeAnalysis_Surface( rts ); |
171 | if ( !sast->IsUClosed(Precision())) { |
172 | doSplit = Standard_True; |
173 | Standard_Real step = (Ul-Uf)/(myNbSplit+1); |
174 | Standard_Real val = Uf+step; |
175 | for(Standard_Integer i = 1; i <= myNbSplit; i++, val+=step) |
176 | split->Append(val); |
177 | isUSplit = Standard_True; |
178 | } |
63c629aa |
179 | #ifdef SHAPEUPGRADE_DEB |
7fd59977 |
180 | else cout << "Warning: SU_ClosedFaceDivide: Thin face, not splitted" << endl; |
181 | #endif |
182 | } |
183 | } |
184 | if( vclosed && !doSplit ) { |
185 | surf -> Bounds(U1, U2, V1, V2); |
186 | GeomAdaptor_Surface GAS ( surf ); |
187 | Standard_Real toler = GAS.VResolution ( Precision() ); |
188 | if((V2-V1) - (Vl-Vf) < toler) { |
189 | Handle(Geom_RectangularTrimmedSurface) rts = |
190 | new Geom_RectangularTrimmedSurface(surf,V1,(V2+V1)/2,Standard_False); |
191 | Handle(ShapeAnalysis_Surface) sast = new ShapeAnalysis_Surface( rts ); |
192 | if ( !sast->IsVClosed(Precision())) { |
193 | doSplit = Standard_True; |
194 | Standard_Real step = (Vl-Vf)/(myNbSplit+1); |
195 | Standard_Real val = Vf+step; |
196 | for(Standard_Integer i = 1; i <= myNbSplit; i++, val+=step) |
197 | split->Append(val); |
198 | isUSplit = Standard_False; |
199 | } |
63c629aa |
200 | #ifdef SHAPEUPGRADE_DEB |
7fd59977 |
201 | else cout << "Warning: SU_ClosedFaceDivide: Thin face, not splitted" << endl; |
202 | #endif |
203 | } |
204 | } |
205 | } |
206 | |
207 | if(!doSplit) |
208 | return Standard_False; |
209 | |
210 | SplitSurf->Init ( surf, Uf, Ul, Vf, Vl ); |
211 | if(isUSplit) |
212 | SplitSurf->SetUSplitValues(split); |
213 | else |
214 | SplitSurf->SetVSplitValues(split); |
215 | |
216 | SplitSurf->Perform(mySegmentMode); |
217 | if ( ! SplitSurf->Status ( ShapeExtend_DONE ) ) return Standard_False; |
218 | Handle(ShapeExtend_CompositeSurface) Grid = SplitSurf->ResSurfaces(); |
219 | |
220 | ShapeFix_ComposeShell CompShell; |
221 | CompShell.Init( Grid, L, face, Precision() ); |
222 | CompShell.SetMaxTolerance(MaxTolerance()); |
223 | CompShell.SetContext(Context()); |
224 | CompShell.Perform(); |
225 | if ( CompShell.Status ( ShapeExtend_FAIL ) || |
226 | ! CompShell.Status ( ShapeExtend_DONE ) ) |
227 | myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL2 ); |
228 | |
229 | TopoDS_Shape res = CompShell.Result(); |
230 | myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 ); |
231 | for(TopExp_Explorer exp(res, TopAbs_FACE); exp.More(); exp.Next()) { |
232 | //smh#8 |
233 | TopoDS_Shape tempf = Context()->Apply(exp.Current()); |
234 | TopoDS_Face f = TopoDS::Face(tempf); |
235 | myResult = f; |
236 | if(SplitSurface()) |
237 | Context()->Replace(f,myResult); |
238 | } |
239 | myResult = Context()->Apply(res); |
240 | return Standard_True; |
241 | } |
242 | |
243 | |
244 | //======================================================================= |
245 | //function : SetFaceNumber |
246 | //purpose : |
247 | //======================================================================= |
248 | |
249 | void ShapeUpgrade_ClosedFaceDivide::SetNbSplitPoints(const Standard_Integer num) |
250 | { |
251 | if(num > 0) |
252 | myNbSplit = num; |
253 | } |
254 | |
255 | //======================================================================= |
256 | //function : GetNbSplitPoints |
257 | //purpose : |
258 | //======================================================================= |
259 | |
260 | Standard_Integer ShapeUpgrade_ClosedFaceDivide::GetNbSplitPoints() const |
261 | { |
262 | return myNbSplit; |
263 | } |