0022922: Clean up warnings on uninitialized / unused variables
[occt.git] / src / ShapeAnalysis / ShapeAnalysis.cxx
1 // File:        ShapeAnalysis.cxx
2 // Created:     Thu Jan 20 12:25:31 2000
3 // Author:      data exchange team
4 //              <det@nnov>
5 // pdn 15.11.98 new methods
6 //:n3 abv 08.02.99: PRO17820: ShapeAnalysis::OuterWire instead of BRepTools::OuterWire()
7 // szv #1 05.03.99: PRO15686: compute UV points for Plane surfaces in case of same vertices
8 //#4 szv            S4163: optimizations
9 //:s5 abv 22.04.99  Adding debug printouts in catch {} blocks
10 //%21 pdn 15.04.99 CTS22655
11
12 #include <ShapeAnalysis.ixx>
13
14 // PLANTAGE IsOuterBound, 15-SEP-1998
15 #include <Standard_ErrorHandler.hxx>
16 #include <Standard_Failure.hxx>
17
18 #include <BRep_Tool.hxx>
19 #include <BRepAdaptor_Surface.hxx>
20 #include <BRepTopAdaptor_FClass2d.hxx>
21 #include <BRepGProp.hxx>
22
23 #include <gp_Pnt2d.hxx>
24 #include <gp_XY.hxx>
25 #include <Geom2d_Curve.hxx>
26 #include <GProp_GProps.hxx>
27
28 #include <ShapeAnalysis_Edge.hxx>
29
30 #include <TopoDS_Wire.hxx>
31 #include <TopoDS_Edge.hxx>
32 #include <TopoDS_Vertex.hxx>
33 #include <TopoDS.hxx>
34 #include <TopoDS_Iterator.hxx>
35 #include <TopExp_Explorer.hxx>
36 #include <BRep_Builder.hxx>
37
38 #include <Precision.hxx>
39 #include <Geom_Surface.hxx>
40 #include <Geom_Plane.hxx>
41 #include <Bnd_Box2d.hxx>
42 #include <ShapeAnalysis_Curve.hxx>
43
44 #include <TColgp_SequenceOfPnt2d.hxx>
45 #include <TColgp_SequenceOfPnt.hxx>
46 #include <Precision.hxx>
47
48 #include <BRepTools.hxx>
49 #include <TopExp.hxx>
50
51 //static Standard_Integer numpb = 0;
52
53 //=======================================================================
54 //function : AdjustByPeriod
55 //purpose  : 
56 //=======================================================================
57
58 Standard_Real ShapeAnalysis::AdjustByPeriod(const Standard_Real Val,
59                                             const Standard_Real ToVal,
60                                             const Standard_Real Period)
61 {
62   Standard_Real diff = Val - ToVal;
63   Standard_Real D = Abs ( diff );
64   Standard_Real P = Abs ( Period );
65   if ( D <= 0.5 * P ) return 0.;
66   if ( P < 1e-100 ) return diff;
67   return ( diff >0 ? -P : P ) * floor( D / P + 0.5 );
68 }
69
70 //=======================================================================
71 //function : AdjustToPeriod
72 //purpose  : 
73 //=======================================================================
74
75 Standard_Real ShapeAnalysis::AdjustToPeriod(const Standard_Real Val,
76                                             const Standard_Real ValMin,
77                                             const Standard_Real ValMax)
78 {
79   return AdjustByPeriod ( Val, 0.5 * ( ValMin + ValMax ), ValMax - ValMin );
80 }
81
82 //=======================================================================
83 //function : FindBounds
84 //purpose  : 
85 //=======================================================================
86
87  void ShapeAnalysis::FindBounds(const TopoDS_Shape& shape,TopoDS_Vertex& V1,TopoDS_Vertex& V2) 
88 {
89   V1.Nullify();
90   V2.Nullify();
91   ShapeAnalysis_Edge EA;
92   if (shape.ShapeType() == TopAbs_WIRE) {
93     TopoDS_Wire W = TopoDS::Wire(shape);
94     //invalid work with reversed wires replaced on TopExp
95     TopExp::Vertices(W,V1,V2);
96     //invalid work with reversed wires
97     /*TopoDS_Iterator iterWire(W);
98     //szv#4:S4163:12Mar99 optimized
99     if (iterWire.More()) {
100       TopoDS_Edge E = TopoDS::Edge (iterWire.Value());
101       V1 = EA.FirstVertex (E); iterWire.Next();
102       for ( ; iterWire.More(); iterWire.Next() ) E = TopoDS::Edge (iterWire.Value());
103       V2 = EA.LastVertex (E);
104     }*/
105   }
106   else if (shape.ShapeType() == TopAbs_EDGE) {
107     V1 = EA.FirstVertex (TopoDS::Edge (shape));
108     V2 = EA.LastVertex (TopoDS::Edge (shape));
109   }
110   else if (shape.ShapeType() == TopAbs_VERTEX)
111     V1 = V2 = TopoDS::Vertex (shape);
112 }
113
114
115 //=======================================================================
116 //function : ReverceSeq
117 //purpose  : auxilary
118 //=======================================================================
119 template<class HSequence> 
120 static inline void ReverceSeq (HSequence& Seq)
121 {
122   Standard_Integer j=Seq.Length();
123   for(Standard_Integer i=1; i<Seq.Length(); i++) {
124     if(i>=j) break;
125     Seq.Exchange(i,j);
126     j--;
127   }
128 }
129 //=======================================================================
130 //function : TotCross2D
131 //purpose  : 
132 //=======================================================================
133
134 Standard_Real ShapeAnalysis::TotCross2D(const Handle(ShapeExtend_WireData)& sewd,
135                                         const TopoDS_Face& aFace)
136 {
137   Standard_Integer i, nbc = 0;
138   gp_Pnt2d fuv,luv, uv0;
139   Standard_Real totcross=0;
140   for(i=1; i<=sewd->NbEdges(); i++) {
141     TopoDS_Edge edge = sewd->Edge(i);
142     Standard_Real f2d, l2d;
143     Handle(Geom2d_Curve) c2d = BRep_Tool::CurveOnSurface(edge,aFace,f2d,l2d);
144     if ( !c2d.IsNull() ) {
145       nbc++;
146       TColgp_SequenceOfPnt2d SeqPnt;
147       ShapeAnalysis_Curve::GetSamplePoints (c2d, f2d, l2d, SeqPnt);
148       if( edge.Orientation()==1 )
149         ReverceSeq(SeqPnt);
150       if(nbc==1)  {
151         fuv=SeqPnt.Value(1);
152         uv0=fuv;
153       }
154       Standard_Integer j=1;
155       for( ; j<=SeqPnt.Length(); j++) {
156         luv = SeqPnt.Value(j);
157         totcross += (fuv.X()-luv.X())*(fuv.Y()+luv.Y())/2;
158         fuv=luv;
159       }
160     }
161   }
162   totcross += (fuv.X()-uv0.X())*(fuv.Y()+uv0.Y())/2;
163   return totcross;
164 }
165
166 //=======================================================================
167 //function : ContourArea
168 //purpose  : 
169 //=======================================================================
170
171 Standard_Real ShapeAnalysis::ContourArea(const TopoDS_Wire& theWire)
172                                          //const Handle(ShapeExtend_WireData)& sewd)
173                                         
174 {
175   Standard_Integer nbc = 0;
176   gp_Pnt fuv,luv, uv0;
177   //Standard_Real totcross=0;
178   gp_XYZ aTotal(0.,0.,0.);
179   TopoDS_Iterator aIte(theWire,Standard_False);
180   //for(i=1; i<=sewd->NbEdges(); i++) {
181   for( ; aIte.More(); aIte.Next()) {
182     TopoDS_Edge edge = TopoDS::Edge(aIte.Value()); //sewd->Edge(i);
183     Standard_Real first, last;
184     Handle(Geom_Curve) c3d = BRep_Tool::Curve(edge,first, last);
185     if ( !c3d.IsNull() ) {
186       
187       TColgp_SequenceOfPnt aSeqPnt;
188       if(!ShapeAnalysis_Curve::GetSamplePoints (c3d, first, last, aSeqPnt))
189         continue;
190       nbc++;
191       if( edge.Orientation()==TopAbs_REVERSED )
192         ReverceSeq(aSeqPnt);
193       if(nbc==1)  {
194         fuv=aSeqPnt.Value(1);
195         uv0=fuv;
196       }
197       Standard_Integer j=1;
198       for( ; j<=aSeqPnt.Length(); j++) {
199         luv = aSeqPnt.Value(j);
200         aTotal += luv.XYZ()^ fuv.XYZ();//
201         fuv=luv;
202       }
203     }
204   }
205   aTotal += uv0.XYZ()^fuv.XYZ();//
206   Standard_Real anArea = aTotal.Modulus()*0.5;
207   return anArea;
208 }
209 //=======================================================================
210 //function : IsOuterBound
211 //purpose  : 
212 //=======================================================================
213
214 Standard_Boolean ShapeAnalysis::IsOuterBound(const TopoDS_Face& face) 
215 {
216   TopoDS_Face F = face;
217   TopoDS_Wire W;
218   F.Orientation(TopAbs_FORWARD);
219   Standard_Integer nbw = 0;
220   for (TopExp_Explorer exp(F,TopAbs_WIRE); exp.More(); exp.Next()) {
221     W = TopoDS::Wire   (exp.Current());  nbw ++;
222   }
223   //skl 08.04.2002
224   if (nbw == 1) {
225     Handle(ShapeExtend_WireData) sewd = new ShapeExtend_WireData(W);
226     Standard_Real totcross = TotCross2D(sewd,F);
227     return (totcross >= 0);
228   }
229   else {
230     BRepAdaptor_Surface Ads ( F, Standard_False ); 
231     Standard_Real tol = BRep_Tool::Tolerance(F);
232     Standard_Real toluv = Min ( Ads.UResolution(tol), Ads.VResolution(tol) );
233     BRepTopAdaptor_FClass2d fcl (F,toluv);
234     Standard_Boolean rescl = (fcl.PerformInfinitePoint () == TopAbs_OUT);
235     return rescl;
236   }
237   return Standard_True;
238 }
239
240 //=======================================================================
241 //function : OuterBound
242 //purpose  : replacement of bad BRepTools::OuterBound()
243 //=======================================================================
244 //:n3
245
246 TopoDS_Wire ShapeAnalysis::OuterWire(const TopoDS_Face& face) 
247 {
248   TopoDS_Face F = face;
249   F.Orientation(TopAbs_FORWARD);
250
251   BRep_Builder B;
252   TopoDS_Wire W;
253   TopoDS_Iterator exp (F, Standard_False);
254   while ( exp.More() ) {
255     if(exp.Value().ShapeType() != TopAbs_WIRE)
256       continue;
257     W = TopoDS::Wire ( exp.Value() );
258     exp.Next();
259     if ( ! exp.More() ) return W;
260     //szv#4:S4163:12Mar99 SGI warns
261     TopoDS_Shape sh = F.EmptyCopied();
262     TopoDS_Face fc = TopoDS::Face( sh );
263     B.Add ( fc, W );
264     if ( ShapeAnalysis::IsOuterBound ( fc ) ) return W;
265   }
266   return W;
267 }
268
269 //=======================================================================
270 //function : GetFaceUVBounds
271 //purpose  : 
272 //=======================================================================
273
274 void ShapeAnalysis::GetFaceUVBounds (const TopoDS_Face& F, 
275                                      Standard_Real& UMin, Standard_Real& UMax, 
276                                      Standard_Real& VMin, Standard_Real& VMax) 
277 {
278   TopoDS_Face FF = F;
279   FF.Orientation(TopAbs_FORWARD);
280   TopExp_Explorer ex(FF,TopAbs_EDGE);
281   if (!ex.More()) {
282     TopLoc_Location L;
283     BRep_Tool::Surface(F,L)->Bounds(UMin,UMax,VMin,VMax);
284     return;
285   }
286   
287   Bnd_Box2d B;
288   ShapeAnalysis_Edge sae;
289   ShapeAnalysis_Curve sac;
290   for (;ex.More();ex.Next()) {
291     TopoDS_Edge edge = TopoDS::Edge(ex.Current());
292     Handle(Geom2d_Curve) c2d;
293     Standard_Real f, l;
294     if ( ! sae.PCurve ( edge, F, c2d, f, l, Standard_False ) ) continue;
295     sac.FillBndBox ( c2d, f, l, 20, Standard_True, B );
296   }
297   B.Get(UMin,VMin,UMax,VMax);
298 }