0030895: Coding Rules - specify std namespace explicitly for std::cout and streams
[occt.git] / src / ShapeUpgrade / ShapeUpgrade_ClosedFaceDivide.cxx
CommitLineData
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 43IMPLEMENT_STANDARD_RTTIEXT(ShapeUpgrade_ClosedFaceDivide,ShapeUpgrade_FaceDivide)
44
7fd59977 45//=======================================================================
46//function : ShapeUpgrade_ClosedFaceDivide
47//purpose :
48//=======================================================================
7fd59977 49ShapeUpgrade_ClosedFaceDivide::ShapeUpgrade_ClosedFaceDivide():
50 ShapeUpgrade_FaceDivide()
51{
52 myNbSplit = 1;
53}
54
55//=======================================================================
56//function : ShapeUpgrade_ClosedFaceDivide
57//purpose :
58//=======================================================================
59
60ShapeUpgrade_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
71Standard_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
04232180 183 else std::cout << "Warning: SU_ClosedFaceDivide: Thin face, not splitted" << std::endl;
7fd59977 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
04232180 204 else std::cout << "Warning: SU_ClosedFaceDivide: Thin face, not splitted" << std::endl;
7fd59977 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
252void 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
263Standard_Integer ShapeUpgrade_ClosedFaceDivide::GetNbSplitPoints() const
264{
265 return myNbSplit;
266}