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