0031671: Coding Rules - eliminate warnings issued by clang 11
[occt.git] / src / ShapeAnalysis / ShapeAnalysis_FreeBoundsProperties.cxx
CommitLineData
b311480e 1// Created on: 1998-08-04
2// Created by: Pavel DURANDIN
3// Copyright (c) 1998-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.
b311480e 16
7fd59977 17// 25.12.98 pdn renaming of ShapeAnalysis_FreeBounds and ShapeAnalysis_Wire methods
18//szv#4 S4163
19
42cf5bc1 20#include <BRep_Builder.hxx>
21#include <BRepTools_WireExplorer.hxx>
22#include <Geom_Curve.hxx>
23#include <GeomAPI_ProjectPointOnCurve.hxx>
24#include <gp_Pnt.hxx>
25#include <gp_Vec.hxx>
26#include <gp_XYZ.hxx>
27#include <Precision.hxx>
7fd59977 28#include <ShapeAnalysis_Edge.hxx>
7fd59977 29#include <ShapeAnalysis_FreeBoundData.hxx>
42cf5bc1 30#include <ShapeAnalysis_FreeBounds.hxx>
31#include <ShapeAnalysis_FreeBoundsProperties.hxx>
32#include <ShapeAnalysis_Wire.hxx>
7fd59977 33#include <ShapeExtend_Explorer.hxx>
34#include <ShapeExtend_WireData.hxx>
7fd59977 35#include <TopoDS.hxx>
36#include <TopoDS_Edge.hxx>
42cf5bc1 37#include <TopoDS_Shape.hxx>
38#include <TopoDS_Wire.hxx>
7fd59977 39#include <TopTools_HSequenceOfShape.hxx>
40
7fd59977 41#define NbControl 23
42
43static void ContourProperties(TopoDS_Wire wire,
44 Standard_Real& countourArea,
45 Standard_Real& countourLength)
46{
47 Standard_Integer nbe = 0;
48 Standard_Real length = 0.0;
49 gp_XYZ area(.0,.0,.0);
50 gp_XYZ prev, cont;
51
52 for (BRepTools_WireExplorer exp(wire); exp.More(); exp.Next()) {
53 TopoDS_Edge Edge = exp.Current(); nbe++;
54
55 Standard_Real First, Last;
56 Handle(Geom_Curve) c3d;
57 ShapeAnalysis_Edge sae;
58 if (!sae.Curve3d(Edge,c3d,First,Last)) continue;
59
60 Standard_Integer ibeg = 0;
61 if ( nbe == 1 ) {
62 gp_Pnt pntIni = c3d->Value(First);
63 prev = pntIni.XYZ();
64 cont = prev;
65 ibeg = 1;
66 }
67
68 for ( Standard_Integer i = ibeg; i < NbControl; i++) {
69 Standard_Real prm = ((NbControl-1-i)*First + i*Last)/(NbControl-1);
70 gp_Pnt pntCurr = c3d->Value(prm);
71 gp_XYZ curr = pntCurr.XYZ();
72 gp_XYZ delta = curr - prev;
73 length += delta.Modulus();
74 area += curr ^ prev;
75 prev = curr;
76 }
77 }
78
79 area += cont ^ prev;
80 countourArea = area.Modulus()/2;
81 countourLength = length;
82}
83
84//=======================================================================
85//function : ShapeAnalysis_FreeBoundsProperties
86//purpose : Empty constructor
87//=======================================================================
88
89ShapeAnalysis_FreeBoundsProperties::ShapeAnalysis_FreeBoundsProperties()
90{
91 myClosedFreeBounds = new ShapeAnalysis_HSequenceOfFreeBounds();
92 myOpenFreeBounds = new ShapeAnalysis_HSequenceOfFreeBounds();
93 myTolerance = 0.;
94}
95
96//=======================================================================
97//function : ShapeAnalysis_FreeBoundsProperties
98//purpose : Creates the object and calls corresponding Init.
99// <shape> should be a compound of faces.
100//=======================================================================
101
102ShapeAnalysis_FreeBoundsProperties::ShapeAnalysis_FreeBoundsProperties(const TopoDS_Shape& shape,
103 const Standard_Real tolerance,
104 const Standard_Boolean splitclosed,
105 const Standard_Boolean splitopen)
106{
107 myClosedFreeBounds = new ShapeAnalysis_HSequenceOfFreeBounds();
108 myOpenFreeBounds = new ShapeAnalysis_HSequenceOfFreeBounds();
109 Init(shape, tolerance, splitclosed, splitopen);
110}
111
112//=======================================================================
113//function : ShapeAnalysis_FreeBoundsProperties
114//purpose : Creates the object and calls corresponding Init.
115// <shape> should be a compound of shells.
116//=======================================================================
117
118ShapeAnalysis_FreeBoundsProperties::ShapeAnalysis_FreeBoundsProperties(const TopoDS_Shape& shape,
119 const Standard_Boolean splitclosed,
120 const Standard_Boolean splitopen)
121{
122 myClosedFreeBounds = new ShapeAnalysis_HSequenceOfFreeBounds();
123 myOpenFreeBounds = new ShapeAnalysis_HSequenceOfFreeBounds();
124 myTolerance =0.;
125 Init(shape, splitclosed, splitopen);
126}
127
128//=======================================================================
129//function : Init
130//purpose : Initializes the object with given parameters.
131// <shape> should be a compound of faces.
132//=======================================================================
133
134void ShapeAnalysis_FreeBoundsProperties::Init(const TopoDS_Shape& shape,
135 const Standard_Real tolerance,
136 const Standard_Boolean splitclosed,
137 const Standard_Boolean splitopen)
138{
139 Init(shape, splitclosed, splitopen);
140 myTolerance = tolerance;
141}
142
143
144//=======================================================================
145//function : Init
146//purpose : Initializes the object with given parameters.
147// <shape> should be a compound of shells.
148//=======================================================================
149
150void ShapeAnalysis_FreeBoundsProperties::Init(const TopoDS_Shape& shape,
151 const Standard_Boolean splitclosed,
152 const Standard_Boolean splitopen)
153{
154 myShape = shape;
155 mySplitClosed = splitclosed;
156 mySplitOpen = splitopen;
157}
158
159
160//=======================================================================
161//function : Perform
162//purpose : Builds and analyzes free bounds of the shape.
163// First calls ShapeAnalysis_FreeBounds for building free
164// bounds.
165// Then on each free bound computes its properties:
166// - area of the contour,
167// - perimeter of the contour,
168// - ratio of average length to average width of the contour,
169// - average width of contour,
170// - notches on the contour and for each notch
171// - maximum width of the notch.
172//returns: True - if no fails and free bounds are found,
173// False - if fail or no free bounds are found
174//=======================================================================
175
176Standard_Boolean ShapeAnalysis_FreeBoundsProperties::Perform()
177{
178 Standard_Boolean result = Standard_False;
179 result |= DispatchBounds();
180 result |= CheckNotches();
181 result |= CheckContours();
182 return result;
183}
184
185
186//=======================================================================
187//function : DispatchBounds
188//purpose :
189//=======================================================================
190
191Standard_Boolean ShapeAnalysis_FreeBoundsProperties::DispatchBounds()
192{
193 if (!IsLoaded()) return Standard_False;
194
195 TopoDS_Compound tmpClosedBounds, tmpOpenBounds;
196 if ( myTolerance > 0.) {
197 ShapeAnalysis_FreeBounds safb(myShape, myTolerance, mySplitClosed, mySplitOpen);
198 tmpClosedBounds = safb.GetClosedWires();
199 tmpOpenBounds = safb.GetOpenWires();
200 }
201 else {
202 ShapeAnalysis_FreeBounds safb(myShape, mySplitClosed, mySplitOpen);
203 tmpClosedBounds = safb.GetClosedWires();
204 tmpOpenBounds = safb.GetOpenWires();
205 }
206
207 ShapeExtend_Explorer shexpl;
208 Handle(TopTools_HSequenceOfShape) tmpSeq = shexpl.SeqFromCompound(tmpClosedBounds,Standard_False);
209 Standard_Integer i; // svv Jan11 2000 : porting on DEC
210 for (i = 1; i<=tmpSeq->Length(); i++) {
211 TopoDS_Wire wire = TopoDS::Wire(tmpSeq->Value(i));
212 Handle(ShapeAnalysis_FreeBoundData) fbData= new ShapeAnalysis_FreeBoundData() ;
213 fbData->SetFreeBound(wire);
214 myClosedFreeBounds -> Append(fbData);
215 }
216
217 Handle(TopTools_HSequenceOfShape) tmpSeq2 = shexpl.SeqFromCompound(tmpOpenBounds,Standard_False);
218 for(i = 1; i<=tmpSeq2->Length(); i++) {
219 TopoDS_Wire wire = TopoDS::Wire(tmpSeq2->Value(i));
220 Handle(ShapeAnalysis_FreeBoundData) fbData = new ShapeAnalysis_FreeBoundData;
221 fbData->SetFreeBound(wire);
222 myOpenFreeBounds -> Append(fbData);
223 }
224
225 return Standard_True;
226}
227
228
229//=======================================================================
230//function : CheckNotches
231//purpose :
232//=======================================================================
233
234Standard_Boolean ShapeAnalysis_FreeBoundsProperties::CheckNotches(const Standard_Real prec)
235{
236 Standard_Integer i; // svv Jan11 2000 : porting on DEC
237 for(i = 1; i <= myClosedFreeBounds->Length(); i++) {
238 Handle(ShapeAnalysis_FreeBoundData) fbData = myClosedFreeBounds->Value(i);
239 CheckNotches(fbData, prec);
240 }
241 for( i = 1; i <= myOpenFreeBounds->Length(); i++) {
242 Handle(ShapeAnalysis_FreeBoundData) fbData = myOpenFreeBounds->Value(i);
243 CheckNotches(fbData, prec);
244 }
245
246 return Standard_True;
247}
248
249//=======================================================================
250//function : CheckNotches
251//purpose :
252//=======================================================================
253
254Standard_Boolean ShapeAnalysis_FreeBoundsProperties::CheckNotches(Handle(ShapeAnalysis_FreeBoundData)& fbData,
255 const Standard_Real prec)
256{
257 ShapeExtend_WireData swd(fbData->FreeBound());
258 if (swd.NbEdges() > 1)
259 for (Standard_Integer j=1; j <= swd.NbEdges(); j++) {
260 TopoDS_Wire notch;
261 Standard_Real dMax;
262 if (CheckNotches(fbData->FreeBound(), j, notch, dMax, prec))
263 fbData->AddNotch(notch, dMax);
264 }
265
266 return Standard_True;
267}
268
269//=======================================================================
270//function : CheckContours
271//purpose :
272//=======================================================================
273
274Standard_Boolean ShapeAnalysis_FreeBoundsProperties::CheckContours(const Standard_Real prec)
275{
276 Standard_Boolean status = Standard_False;
277 Standard_Integer i; // svv Jan11 2000 : porting on DEC
278 for( i = 1; i <= myClosedFreeBounds->Length(); i++) {
279 Handle(ShapeAnalysis_FreeBoundData) fbData = myClosedFreeBounds->Value(i);
280 status |= FillProperties(fbData,prec);
281 }
282 for ( i = 1; i <= myOpenFreeBounds->Length(); i++) {
283 Handle(ShapeAnalysis_FreeBoundData) fbData = myOpenFreeBounds->Value(i);
284 status |= FillProperties(fbData,prec);
285 }
286
287 return status;
288}
289
290
291//=======================================================================
292//function : CheckNotches
293//purpose :
294//=======================================================================
295
296Standard_Boolean ShapeAnalysis_FreeBoundsProperties::CheckNotches(const TopoDS_Wire& wire,
297 const Standard_Integer num,
298 TopoDS_Wire& notch,
299 Standard_Real& distMax,
300 const Standard_Real /*prec*/)
301{
302 Standard_Real tol = Max ( myTolerance, Precision::Confusion());
303 Handle(ShapeExtend_WireData) wdt = new ShapeExtend_WireData(wire);
304 BRep_Builder B;
305 B.MakeWire(notch);
306
307 if ( (num <= 0)||(num > wdt->NbEdges()) ) return Standard_False;
308
309 Standard_Integer n1 = ( num > 0 ? num : wdt->NbEdges() );
310 Standard_Integer n2 = ( n1 < wdt->NbEdges() ? n1+1 : 1 );
311
312 TopoDS_Edge E1 = wdt->Edge(n1);
313 B.Add(notch,E1);
314
315 Handle(ShapeAnalysis_Wire) saw = new ShapeAnalysis_Wire;
316 saw->Load(wdt);
317 saw->SetPrecision(myTolerance);
318 if ( saw->CheckSmall( n2, tol ) ) {
319 B.Add(notch,wdt->Edge(n2));
320 n2 = ( n2 < wdt->NbEdges() ? n2+1 : 1);
321 }
322
323 TopoDS_Edge E2 = wdt->Edge(n2);
324 B.Add(notch,E2);
325
326 Standard_Real First1, Last1, First2, Last2;
327 Handle(Geom_Curve) c3d1, c3d2;
328 ShapeAnalysis_Edge sae;
329 //szv#4:S4163:12Mar99 optimized
330 if ( !sae.Curve3d(E1, c3d1, First1, Last1) ||
331 !sae.Curve3d(E2, c3d2, First2, Last2) ) return Standard_False;
332
333 gp_Pnt pnt;
334 gp_Vec vec1, vec2;
335 c3d1->D1(Last1, pnt, vec1);
336 c3d2->D1(First2,pnt, vec2);
337 if ( E1.Orientation() == TopAbs_REVERSED ) vec1.Reverse();
338 if ( E2.Orientation() == TopAbs_REVERSED ) vec2.Reverse();
339
340 Standard_Real angl = Abs( vec1.Angle(vec2));
c6541a0c 341 if (angl > 0.95*M_PI) {
7fd59977 342 distMax = .0;
343 for (Standard_Integer i = 0; i < NbControl; i++) {
344 Standard_Real prm = ((NbControl-1-i)*First1 + i*Last1)/(NbControl-1);
345 gp_Pnt pntCurr = c3d1->Value(prm);
346
347 Standard_Real p1, p2;
348 if ( First2 < Last2 ) {
349 p1 = First2;
350 p2 = Last2;
351 }
352 else {
353 p1 = Last2;
354 p2 = First2;
355 }
356
357 //szv#4:S4163:12Mar99 warning
358 GeomAPI_ProjectPointOnCurve ppc(pntCurr, c3d2, p1, p2);
359 Standard_Real newDist = (ppc.NbPoints() ? ppc.LowerDistance() : 0);
360 if ( newDist > distMax ) distMax = newDist;
361 }
362
363 return Standard_True;
364 }
365
366 return Standard_False;
367}
368
369
370//=======================================================================
371//function : FillProperties
372//purpose :
373//=======================================================================
374
375Standard_Boolean ShapeAnalysis_FreeBoundsProperties::FillProperties(Handle(ShapeAnalysis_FreeBoundData)& fbData,
376 const Standard_Real /*prec*/)
377{
378 Standard_Real area, length;
379 ContourProperties(fbData->FreeBound(), area, length);
380
381 Standard_Real r = 0;
382 Standard_Real aver = 0;
383
384 if ( length != 0. ) { //szv#4:S4163:12Mar99 anti-exception
385 Standard_Real k = area /(length*length); //szv#4:S4163:12Mar99
386 //szv#4:S4163:12Mar99 optimized
387 if ( k != 0. ) { //szv#4:S4163:12Mar99 anti-exception
388 Standard_Real aux = 1. - 16.*k;
389 if ( aux >= 0.) {
390 r = (1. + sqrt(aux))/(8.*k);
391 aver = length/(2.*r);
392 r -= 1.;
393 }
394 }
395 }
396
397 fbData->SetArea(area);
398 fbData->SetPerimeter(length);
399 fbData->SetRatio(r);
400 fbData->SetWidth(aver);
401
402 return Standard_True;
403}