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