0024002: Overall code and build procedure refactoring -- automatic
[occt.git] / src / ShapeAnalysis / ShapeAnalysis_Edge.cxx
CommitLineData
973c2be1 1// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 2//
973c2be1 3// This file is part of Open CASCADE Technology software library.
b311480e 4//
d5f74e42 5// This library is free software; you can redistribute it and/or modify it under
6// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 7// by the Free Software Foundation, with special exception defined in the file
8// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9// distribution for complete text of the license and disclaimer of any warranty.
b311480e 10//
973c2be1 11// Alternatively, this file may be used under the terms of Open CASCADE
12// commercial license or contractual agreement.
b311480e 13
7fd59977 14//:o8 abv 19.02.99: CTS18541.stp #18559: coeff 1.0001 added in CheckVertexTol
15//:p1 abv 22.02.99: protection against edges with no vertices (infinite)
16//szv#4 S4163
17//:s1 abv 22.04.99: PRO7226 #489490: protect against Null 3d curve
18//:s4 abv 26.04.99: sim6049.igs 21677: copy of curve is necessary to get True SP
19// abv 06.05.99: S4137: adding methods GetTangent2d()
7fd59977 20
7fd59977 21#include <Adaptor3d_Curve.hxx>
22#include <Adaptor3d_CurveOnSurface.hxx>
42cf5bc1 23#include <BRep_Builder.hxx>
7fd59977 24#include <BRep_GCurve.hxx>
25#include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
42cf5bc1 26#include <BRep_TEdge.hxx>
27#include <BRep_Tool.hxx>
28#include <BRepAdaptor_Curve.hxx>
29#include <BRepExtrema_DistShapeShape.hxx>
7fd59977 30#include <Extrema_LocateExtPC.hxx>
42cf5bc1 31#include <GCPnts_AbscissaPoint.hxx>
32#include <Geom2d_Curve.hxx>
33#include <Geom2dAdaptor_HCurve.hxx>
34#include <Geom_Curve.hxx>
35#include <Geom_Plane.hxx>
36#include <Geom_Surface.hxx>
37#include <GeomAdaptor_Curve.hxx>
38#include <GeomAdaptor_HSurface.hxx>
39#include <gp_Pnt.hxx>
40#include <gp_Pnt2d.hxx>
41#include <gp_Vec2d.hxx>
42#include <Precision.hxx>
43#include <ShapeAnalysis_Edge.hxx>
7fd59977 44#include <ShapeExtend.hxx>
42cf5bc1 45#include <Standard_ErrorHandler.hxx>
46#include <Standard_Failure.hxx>
7fd59977 47#include <TopExp.hxx>
42cf5bc1 48#include <TopLoc_Location.hxx>
49#include <TopoDS_Edge.hxx>
50#include <TopoDS_Face.hxx>
7fd59977 51#include <TopoDS_Vertex.hxx>
7fd59977 52
53//=======================================================================
54//function : ShapeAnalysis_Edge
55//purpose :
56//=======================================================================
7fd59977 57ShapeAnalysis_Edge::ShapeAnalysis_Edge()
58{
59 myStatus = 0;//ShapeExtend::EncodeStatus (ShapeExtend_OK);
60}
61
62
63//=======================================================================
64//function : BoundUV
65//purpose :
66//=======================================================================
67
68Standard_Boolean ShapeAnalysis_Edge::BoundUV (const TopoDS_Edge& edge,
69 const TopoDS_Face& face,
70 gp_Pnt2d& first, gp_Pnt2d& last) const
71{
72 TopLoc_Location L;
73 const Handle(Geom_Surface) S = BRep_Tool::Surface(face, L);
74 return BoundUV (edge, S, L, first, last);
75}
76
77
78//=======================================================================
79//function : BoundUV
80//purpose :
81//=======================================================================
82
83Standard_Boolean ShapeAnalysis_Edge::BoundUV (const TopoDS_Edge& edge,
84 const Handle(Geom_Surface)& surface,
85 const TopLoc_Location& location,
86 gp_Pnt2d& first, gp_Pnt2d& last) const
87{
88 Handle(Geom2d_Curve) c2d;
89 Standard_Real uf,ul;
90 if (!PCurve (edge, surface, location, c2d, uf, ul)) return Standard_False;
91 first = c2d->Value (uf);
92 last = c2d->Value (ul);
93 return Standard_True;
94}
95
96
97//=======================================================================
98//function : HasCurve3d
99//purpose :
100//=======================================================================
101
102Standard_Boolean ShapeAnalysis_Edge::HasCurve3d (const TopoDS_Edge& edge) const
103{
104 Standard_Real cf, cl;
105 Handle(Geom_Curve) c3d = BRep_Tool::Curve (edge, cf, cl);
106 return !c3d.IsNull();
107}
108
109
110//=======================================================================
111//function : Curve3d
112//purpose :
113//=======================================================================
114
115Standard_Boolean ShapeAnalysis_Edge::Curve3d (const TopoDS_Edge& edge,
116 Handle(Geom_Curve)& C3d,
117 Standard_Real& cf, Standard_Real& cl,
118 const Standard_Boolean orient) const
119{
120 TopLoc_Location L;
121 C3d = BRep_Tool::Curve (edge, L, cf, cl);
122 if( !C3d.IsNull() && !L.IsIdentity() ) {
123 C3d = Handle(Geom_Curve)::DownCast(C3d->Transformed(L.Transformation()));
124 cf = C3d->TransformedParameter(cf, L.Transformation());
125 cl = C3d->TransformedParameter(cl, L.Transformation());
126 }
127 if (orient) {
128 if (edge.Orientation() == TopAbs_REVERSED)
129 {Standard_Real tmp = cf; cf = cl; cl = tmp;}
130 }
131 return !C3d.IsNull();
132}
133
134
135//=======================================================================
136//function : IsClosed3d
137//purpose :
138//=======================================================================
139
140Standard_Boolean ShapeAnalysis_Edge::IsClosed3d (const TopoDS_Edge& edge) const
141{
142 Standard_Real cf,cl;
143 Handle(Geom_Curve) c3d = BRep_Tool::Curve (edge,cf,cl);
144 if (c3d.IsNull()) return Standard_False;
145 if (!c3d->IsClosed()) return Standard_False;
146 return FirstVertex (edge).IsSame (LastVertex (edge));
147}
148
149
150//=======================================================================
151//function : HasPCurve
152//purpose :
153//=======================================================================
154
155Standard_Boolean ShapeAnalysis_Edge::HasPCurve (const TopoDS_Edge& edge,
156 const TopoDS_Face& face) const
157{
158 TopLoc_Location L;
159 const Handle(Geom_Surface)& S = BRep_Tool::Surface(face, L);
160 return HasPCurve (edge, S, L);
161}
162
163
164//=======================================================================
165//function : HasPCurve
166//purpose :
167//=======================================================================
168
169Standard_Boolean ShapeAnalysis_Edge::HasPCurve (const TopoDS_Edge& edge,
170 const Handle(Geom_Surface)& surface,
171 const TopLoc_Location& location) const
172{
173 //try { //szv#4:S4163:12Mar99 waste try
174 Standard_Real cf, cl;
175 Handle(Geom2d_Curve) c2d = BRep_Tool::CurveOnSurface (edge, surface, location, cf, cl);
176 return !c2d.IsNull();
177 /* }
178 catch (Standard_Failure) {
179 }
180 return Standard_False; */
181}
182
183
184//=======================================================================
185//function : PCurve
186//purpose :
187//=======================================================================
188
189Standard_Boolean ShapeAnalysis_Edge::PCurve (const TopoDS_Edge& edge,
190 const TopoDS_Face& face,
191 Handle(Geom2d_Curve)& C2d,
192 Standard_Real& cf, Standard_Real& cl,
193 const Standard_Boolean orient) const
194{
195 //:abv 20.05.02: take into account face orientation
196 // COMMENTED BACK - NEEDS MORE CHANGES IN ALL SHAPEHEALING
197// C2d = BRep_Tool::CurveOnSurface (edge, face, cf, cl);
198// if (orient && edge.Orientation() == TopAbs_REVERSED) {
199// Standard_Real tmp = cf; cf = cl; cl = tmp;
200// }
201// return !C2d.IsNull();
202 TopLoc_Location L;
203 const Handle(Geom_Surface)& S = BRep_Tool::Surface(face, L);
204 return PCurve (edge, S, L, C2d, cf, cl, orient);
205}
206
207
208//=======================================================================
209//function : PCurve
210//purpose :
211//=======================================================================
212
213Standard_Boolean ShapeAnalysis_Edge::PCurve (const TopoDS_Edge& edge,
214 const Handle(Geom_Surface)& surface,
215 const TopLoc_Location& location,
216 Handle(Geom2d_Curve)& C2d,
217 Standard_Real& cf, Standard_Real& cl,
218 const Standard_Boolean orient) const
219{
220 C2d = BRep_Tool::CurveOnSurface (edge, surface, location, cf, cl);
221 if ( orient && edge.Orientation() == TopAbs_REVERSED ) {
222 Standard_Real tmp = cf; cf = cl; cl = tmp;
223 }
224 return !C2d.IsNull();
225}
226
227
228//=======================================================================
229//function : IsSeam
230//purpose :
231//=======================================================================
232
233Standard_Boolean ShapeAnalysis_Edge::IsSeam (const TopoDS_Edge& edge,
234 const TopoDS_Face& face) const
235{
236 return BRep_Tool::IsClosed (edge, face);
237}
238
239
240//=======================================================================
241//function : IsSeam
242//purpose :
243//=======================================================================
244
245Standard_Boolean ShapeAnalysis_Edge::IsSeam (const TopoDS_Edge& edge,
246 const Handle(Geom_Surface)& surface,
247 const TopLoc_Location& location) const
248{
249 return BRep_Tool::IsClosed (edge, surface, location);
250}
251
252
253//=======================================================================
254//function : FirstVertex
255//purpose :
256//=======================================================================
257
258TopoDS_Vertex ShapeAnalysis_Edge::FirstVertex (const TopoDS_Edge& edge) const
259{
260 TopoDS_Vertex V;
261 if (edge.Orientation() == TopAbs_REVERSED) {
262 V = TopExp::LastVertex(edge);
263 V.Reverse();
264 }
265 else {
266 V = TopExp::FirstVertex (edge);
267 }
268 return V;
269}
270
271
272//=======================================================================
273//function : LastVertex
274//purpose :
275//=======================================================================
276
277TopoDS_Vertex ShapeAnalysis_Edge::LastVertex (const TopoDS_Edge& edge) const
278{
279 TopoDS_Vertex V;
280 if (edge.Orientation() == TopAbs_REVERSED) {
281 V = TopExp::FirstVertex(edge);
282 V.Reverse();
283 }
284 else {
285 V = TopExp::LastVertex (edge);
286 }
287 return V;
288}
289
290
291//=======================================================================
292//function : Status
293//purpose :
294//=======================================================================
295
296Standard_Boolean ShapeAnalysis_Edge::Status (const ShapeExtend_Status Status) const
297{
298 return ShapeExtend::DecodeStatus (myStatus, Status);
299}
300
301
302//=======================================================================
303//function : GetEndTangent2d
304//purpose :
305//=======================================================================
306
307Standard_Boolean ShapeAnalysis_Edge::GetEndTangent2d (const TopoDS_Edge &edge,
308 const TopoDS_Face &face,
309 const Standard_Boolean atend1, /* skl : change "atend" to "atend1" */
310 gp_Pnt2d &pnt,
311 gp_Vec2d &v,
312 const Standard_Real dparam) const
313{
314 TopLoc_Location L;
315 const Handle(Geom_Surface) S = BRep_Tool::Surface ( face, L );
316 return GetEndTangent2d ( edge, S, L, atend1, pnt, v, dparam );
317}
318
319
320//=======================================================================
321//function : GetEndTangent2d
322//purpose :
323//=======================================================================
324
325Standard_Boolean ShapeAnalysis_Edge::GetEndTangent2d (const TopoDS_Edge &edge,
326 const Handle(Geom_Surface)& S,
327 const TopLoc_Location& L,
328 const Standard_Boolean atend2, /* skl : change "atend" to "atend2" */
329 gp_Pnt2d &pnt,
330 gp_Vec2d &v,
331 const Standard_Real dparam) const
332{
333 Standard_Real cf, cl;
334 Handle(Geom2d_Curve) c2d;
335 if ( ! PCurve ( edge, S, L, c2d, cf, cl ) ) {
336 v = gp_Vec2d(0,0);
337 return Standard_False;
338 }
339 Standard_Real dpnew = dparam;
340
341 if(dpnew>Precision::Confusion()) {
342 gp_Pnt2d ptmp;
343 Standard_Real par1,par2,delta=(cl-cf)*dpnew;
344 if(Abs(delta)<Precision::PConfusion()) {
345 dpnew=0.0;
346 }
347 else {
348 if(atend2) {
349 par1 = cl;
350 par2 = cl - delta;
351 c2d->D0(par1,pnt);
352 c2d->D0(par2,ptmp);
353 v = pnt.XY() - ptmp.XY();
354 }
355 else {
356 par1 = cf;
357 par2 = cf + delta;
358 c2d->D0(par1,pnt);
359 c2d->D0(par2,ptmp);
360 v = ptmp.XY() - pnt.XY();
361 }
362 if( v.SquareMagnitude() < Precision::PConfusion()*Precision::PConfusion() ) {
363 dpnew=0.0;
364 }
365 }
366 }
367
368 if(dpnew<=Precision::Confusion()) {
369 // get non-null tangency searching until 3rd derivative, or as straight btw ends
370 Standard_Real par = ( atend2 ? cl : cf );
371 c2d->D1 ( par, pnt, v );
372 if ( v.SquareMagnitude() < Precision::PConfusion()*Precision::PConfusion() ) {
373 gp_Vec2d d1;
374 c2d->D2 ( par, pnt, d1, v );
375 if ( v.SquareMagnitude() < Precision::PConfusion()*Precision::PConfusion() ) {
376 gp_Vec2d d2;
377 c2d->D3 ( par, pnt, d1, d2, v );
378 if ( v.SquareMagnitude() < Precision::PConfusion()*Precision::PConfusion() ) {
379 gp_Pnt2d p2;
380 c2d->D0 ( ( atend2 ? cf : cl ), p2 );
381 v = p2.XY() - pnt.XY();
382 if ( v.SquareMagnitude() < Precision::PConfusion()*Precision::PConfusion() )
383 return Standard_False;
384 }
385 }
386 }
387 if ( edge.Orientation() == TopAbs_REVERSED ) v.Reverse();
388 }
389
390 //if ( edge.Orientation() == TopAbs_REVERSED ) v.Reverse();
391 return Standard_True;
392}
393
394
395//=======================================================================
396//function : CheckCurve3dWithPCurve
397//purpose :
398//=======================================================================
399
400Standard_Boolean ShapeAnalysis_Edge::CheckCurve3dWithPCurve (const TopoDS_Edge& edge,
401 const TopoDS_Face& face)
402{
403 TopLoc_Location L;
404 const Handle(Geom_Surface)& S = BRep_Tool::Surface(face, L);
405 return CheckCurve3dWithPCurve (edge, S, L);
406}
407
408
409//=======================================================================
410//function : CheckCurve3dWithPCurve
411//purpose :
412//=======================================================================
413
414Standard_Boolean ShapeAnalysis_Edge::CheckCurve3dWithPCurve (const TopoDS_Edge& edge,
415 const Handle(Geom_Surface)& surface,
416 const TopLoc_Location& location)
417{
418 myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
419
420 if(surface->IsKind(STANDARD_TYPE(Geom_Plane)))
421 return Standard_False;
422
423 Handle (Geom2d_Curve) c2d;
424 Standard_Real f2d, l2d; //szv#4:S4163:12Mar99 moved down f3d, l3d
425 if (!PCurve (edge, surface, location, c2d, f2d ,l2d, Standard_False)) {
426 myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL1);
427 return Standard_False;
428 }
429
430 Handle (Geom_Curve) c3d; //szv#4:S4163:12Mar99 moved
431 Standard_Real f3d, l3d; //szv#4:S4163:12Mar99 moved
432 if (!Curve3d (edge, c3d, f3d, l3d, Standard_False)) {
433 myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL2);
434 return Standard_False;
435 }
436
46aed280 437 TopoDS_Vertex aFirstVert = FirstVertex (edge);
438 TopoDS_Vertex aLastVert = LastVertex (edge);
439
440 if (aFirstVert.IsNull() || aLastVert.IsNull())
441 return Standard_False;
442
443 Standard_Real preci1 = BRep_Tool::Tolerance (aFirstVert),
444 preci2 = BRep_Tool::Tolerance (aLastVert);
7fd59977 445
446 gp_Pnt2d p2d1 = c2d->Value (f2d),
447 p2d2 = c2d->Value (l2d);
448
449 //#39 rln 17.11.98 S4054, annie_surf.igs entity 39
450 return CheckPoints (c3d->Value (f3d)/*.Transformed (location.Transformation())*/,
451 c3d->Value (l3d)/*.Transformed (location.Transformation())*/,
452 surface->Value (p2d1.X(), p2d1.Y()).Transformed (location.Transformation()),
453 surface->Value (p2d2.X(), p2d2.Y()).Transformed (location.Transformation()),
454 preci1, preci2);
455}
456
457
458//=======================================================================
459//function : CheckPoints
460//purpose :
461//=======================================================================
462
463Standard_Boolean ShapeAnalysis_Edge::CheckPoints (const gp_Pnt& P1A,
464 const gp_Pnt& P1B,
465 const gp_Pnt& P2A,
466 const gp_Pnt& P2B,
467 const Standard_Real preci1,
468 const Standard_Real preci2)
469{
470 myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
471 if (P1A.SquareDistance (P2A) <= preci1 * preci1 &&
472 P1B.SquareDistance (P2B) <= preci2 * preci2)
473 return Standard_False;
474 else if (P1A.Distance (P2B) + (P1B.Distance (P2A)) <
475 P1A.Distance (P2A) + (P1B.Distance (P2B)))
476 myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_DONE1);
477 return Standard_True;
478}
479
480
481//=======================================================================
482//function : CheckVerticesWithCurve3d
483//purpose :
484//=======================================================================
485
486Standard_Boolean ShapeAnalysis_Edge::CheckVerticesWithCurve3d (const TopoDS_Edge& edge,
487 const Standard_Real preci,
488 const Standard_Integer vtx)
489{
490 myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
491
492 TopoDS_Vertex V1 = FirstVertex (edge);
493 TopoDS_Vertex V2 = LastVertex (edge);
494 gp_Pnt p1v = BRep_Tool::Pnt (V1);
495 gp_Pnt p2v = BRep_Tool::Pnt (V2);
496
497 Standard_Real cf,cl;
498 Handle(Geom_Curve) c3d;
499 if ( ! Curve3d (edge,c3d,cf,cl) ) {
500 myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL1);
501 return Standard_False;
502 }
503
504 // on va faire les checks ...
505 if (vtx != 2) {
506 // 1er VTX
507 gp_Pnt p13d = c3d->Value(cf);
508 //szv#4:S4163:12Mar99 optimized
509 if (p1v.Distance(p13d) > (preci < 0 ? BRep_Tool::Tolerance (V1) : preci))
510 myStatus |= ShapeExtend_DONE1;
511 }
512
513 if (vtx != 1) {
514 // 2me VTX
515 gp_Pnt p23d = c3d->Value(cl);
516 //szv#4:S4163:12Mar99 optimized
517 if (p2v.Distance(p23d) > (preci < 0 ? BRep_Tool::Tolerance (V2) : preci))
518 myStatus |= ShapeExtend_DONE2;
519 }
520
521 return Status ( ShapeExtend_DONE );
522}
523
524
525//=======================================================================
526//function : CheckVerticesWithPCurve
527//purpose :
528//=======================================================================
529
530Standard_Boolean ShapeAnalysis_Edge::CheckVerticesWithPCurve (const TopoDS_Edge& edge,
531 const TopoDS_Face& face,
532 const Standard_Real preci,
533 const Standard_Integer vtx)
534{
535 TopLoc_Location L;
536 const Handle(Geom_Surface)& S = BRep_Tool::Surface(face, L);
537 return CheckVerticesWithPCurve (edge, S, L, preci, vtx); //szv#4:S4163:12Mar99 `vtx,preci` wrong parameters order
538}
539
540
541//=======================================================================
542//function : CheckVerticesWithPCurve
543//purpose :
544//=======================================================================
545
546Standard_Boolean ShapeAnalysis_Edge::CheckVerticesWithPCurve (const TopoDS_Edge& edge,
547 const Handle(Geom_Surface)& surf,
548 const TopLoc_Location& loc,
549 const Standard_Real preci,
550 const Standard_Integer vtx)
551{
552 myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK);
553
554 TopoDS_Vertex V1 = FirstVertex (edge);
555 TopoDS_Vertex V2 = LastVertex (edge);
556 gp_Pnt p1v = BRep_Tool::Pnt (V1);
557 gp_Pnt p2v = BRep_Tool::Pnt (V2);
558
559 Standard_Real cf, cl;
560 Handle(Geom2d_Curve) c2d;
561 if ( ! PCurve ( edge, surf, loc, c2d, cf, cl ) ) {
562 myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL1);
563 return Standard_False;
564 }
565
566 // on va faire les checks ...
567 if (vtx != 2) { // 1er VTX
568 gp_Pnt2d p1uv = c2d->Value (cf);
569 gp_Pnt p12d = surf->Value (p1uv.X(), p1uv.Y());
c31e0def 570 if (!loc.IsIdentity())
571 p12d.Transform(loc.Transformation());
7fd59977 572 // szv#4:S4163:12Mar99 optimized
573 if ( p1v.Distance(p12d) > (preci < 0 ? BRep_Tool::Tolerance (V1) : preci) )
574 myStatus |= ShapeExtend_DONE1;
575 }
576
577 if (vtx != 1) { // 2me VTX
578 gp_Pnt2d p2uv = c2d->Value (cl);
579 gp_Pnt p22d = surf->Value (p2uv.X(), p2uv.Y());
c31e0def 580 if (!loc.IsIdentity())
581 p22d.Transform(loc.Transformation());
7fd59977 582 // szv#4:S4163:12Mar99 optimized
583 if ( p2v.Distance(p22d) > (preci < 0 ? BRep_Tool::Tolerance (V2) : preci) )
584 myStatus |= ShapeExtend_DONE2;
585 }
586
587 return Status ( ShapeExtend_DONE );
588}
589
590
591//=======================================================================
592//function : CheckVertexTolerance
593//purpose :
594//=======================================================================
595
596static Standard_Integer CheckVertexTolerance(const TopoDS_Edge& edge,
597 const TopoDS_Face& face,
598 const Standard_Boolean checkAll,
599 Standard_Real& toler1,
600 Standard_Real& toler2)
601{
602 Standard_Integer Status = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
603
604 ShapeAnalysis_Edge sae;
605 TopoDS_Vertex V1 = sae.FirstVertex (edge);
606 TopoDS_Vertex V2 = sae.LastVertex (edge);
607 if ( V1.IsNull() || V2.IsNull() ) { //:p1 abv 22 Feb 99: r76sy.stp
608 Status |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL1);
609 return Status;
610 }
611
612 Standard_Real old1 = BRep_Tool::Tolerance (V1);
613 Standard_Real old2 = BRep_Tool::Tolerance (V2);
614 gp_Pnt pnt1 = BRep_Tool::Pnt (V1);
615 gp_Pnt pnt2 = BRep_Tool::Pnt (V2);
616
617 Standard_Real a, b;
618 Handle(Geom_Curve) c3d;
619 if ( ! sae.Curve3d(edge, c3d, a, b, Standard_True)) {
620 if ( ! BRep_Tool::Degenerated ( edge ) )
621 Status |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL2);
622 toler1 = toler2 = 0.;
623// return Standard_False;
624 }
625 else {
626 toler1 = pnt1.SquareDistance (c3d->Value (a));
627 toler2 = pnt2.SquareDistance (c3d->Value (b));
628 }
629
630 if ( checkAll ) {
631 Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&edge.TShape());
632 for (BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves()); itcr.More(); itcr.Next() ) {
633 Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
634 if (GC.IsNull() || !GC->IsCurveOnSurface()) continue;
635 Handle(Geom2d_Curve) pcurve;
636 Handle(Geom_Surface) S = GC->Surface();
637 TopLoc_Location L = edge.Location() * GC->Location();
638 sae.PCurve (edge, S, L, pcurve, a, b, Standard_True);
639 gp_Pnt2d p1 = pcurve->Value (a);
640 gp_Pnt2d p2 = pcurve->Value (b);
641 gp_Pnt P1 = S->Value (p1.X(), p1.Y()).Transformed (L.Transformation());
642 gp_Pnt P2 = S->Value (p2.X(), p2.Y()).Transformed (L.Transformation());
643 toler1 = Max (toler1, pnt1.SquareDistance (P1));
644 toler2 = Max (toler2, pnt2.SquareDistance (P2));
645 }
646 }
647 //:abv 10.06.02: porting C40 -> dev (CC670-12608.stp)
648 // Check with given face is needed for plane surfaces (if no stored pcurves)
649 else if ( ! face.IsNull() ) {
650 Handle(Geom2d_Curve) pcurve;
651 TopLoc_Location L;
652 const Handle(Geom_Surface)& S = BRep_Tool::Surface(face, L);
653 if ( sae.PCurve(edge, S, L, pcurve, a, b, Standard_True)) {
654 gp_Pnt2d p1 = pcurve->Value (a);
655 gp_Pnt2d p2 = pcurve->Value (b);
656 gp_Pnt P1 = S->Value (p1.X(), p1.Y()).Transformed (L.Transformation());
657 gp_Pnt P2 = S->Value (p2.X(), p2.Y()).Transformed (L.Transformation());
658 toler1 = Max (toler1, pnt1.SquareDistance (P1));
659 toler2 = Max (toler2, pnt2.SquareDistance (P2));
660 }
661 else Status |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL3);
662 }
663
664 //:o8 abv 19 Feb 99: CTS18541.stp #18559: coeff 1.0001 added
665 //szv 18 Aug 99: edge tolerance is taken in consideration
666 Standard_Real tole = BRep_Tool::Tolerance (edge);
667 toler1 = Max (1.0000001 * Sqrt (toler1), tole);
668 toler2 = Max (1.0000001 * Sqrt (toler2), tole);
669 if ( toler1 > old1)
670 Status |= ShapeExtend::EncodeStatus (ShapeExtend_DONE1);
671 if ( toler2 > old2)
672 Status |= ShapeExtend::EncodeStatus (ShapeExtend_DONE2);
673
674 return Status;
675}
676
677
678//=======================================================================
679//function : CheckVertexTolerance
680//purpose :
681//=======================================================================
682
683Standard_Boolean ShapeAnalysis_Edge::CheckVertexTolerance(const TopoDS_Edge& edge,
684 const TopoDS_Face& face,
685 Standard_Real& toler1,
686 Standard_Real& toler2)
687{
688 myStatus = ::CheckVertexTolerance ( edge, face, Standard_False, toler1, toler2 );
689 return Status ( ShapeExtend_DONE );
690}
691
692
693//=======================================================================
694//function : CheckVertexTolerance
695//purpose :
696//=======================================================================
697
698Standard_Boolean ShapeAnalysis_Edge::CheckVertexTolerance(const TopoDS_Edge& edge,
699 Standard_Real& toler1,
700 Standard_Real& toler2)
701{
702 TopoDS_Face F;
703 myStatus = ::CheckVertexTolerance ( edge, F, Standard_True, toler1, toler2 );
704 return Status ( ShapeExtend_DONE );
705}
706
707
708//=======================================================================
709//static : Validate
710//purpose: For SameParameter: compute it for two curves
711//note: This function is made from Validate() in BRepCheck_Edge.cxx
712//=======================================================================
713
5402ccdd
RL
714Standard_Boolean ShapeAnalysis_Edge::ComputeDeviation (const Adaptor3d_Curve& CRef,
715 const Adaptor3d_Curve& Other,
716 const Standard_Boolean SameParameter,
717 Standard_Real &dev,
718 const Standard_Integer NCONTROL)
7fd59977 719{
720 Standard_Boolean OK = Standard_True;
721 Standard_Real dev2 = dev*dev;
722
723 Standard_Real First = CRef.FirstParameter(), Last = CRef.LastParameter();
724 Standard_Real OFirst = Other.FirstParameter(), OLast = Other.LastParameter(); //szv#4:S4163:12Mar99 moved
725
726 Standard_Boolean proj = (!SameParameter || First != OFirst || Last != OLast); //szv#4:S4163:12Mar99 optimized
727
728 Standard_Integer NCtrl = ( NCONTROL < 1 )? 1 : NCONTROL; //szv#4:S4163:12Mar99 anti-exception
729
730 if (!proj) {
731 for (Standard_Integer i = 0; i <= NCtrl; i++) {
732 Standard_Real prm = ((NCtrl-i)*First + i*Last)/NCtrl;
733 gp_Pnt pref = CRef.Value(prm);
734 gp_Pnt pother = Other.Value(prm);
735 Standard_Real dist2 = pref.SquareDistance(pother);
736 if ( dev2 < dist2 ) dev2 = dist2;
737 }
738 dev = Sqrt ( dev2 );
739 }
740 else {
741 gp_Pnt pd = CRef.Value(First);
742 gp_Pnt pdo = Other.Value(OFirst);
743 Standard_Real dist2 = pd.SquareDistance(pdo);
744 if ( dev2 < dist2 ) dev = Sqrt ( dev2 = dist2 );
745
746 pd = CRef.Value(Last);
747 pdo = Other.Value(OLast);
748 dist2 = pd.SquareDistance(pdo);
749 if ( dev2 < dist2 ) dev = Sqrt ( dev2 = dist2 );
750
751 Extrema_LocateExtPC refd, otherd; //szv#4:S4163:12Mar99 warning
752 refd.Initialize(CRef,First,Last,Precision::PConfusion());
753 otherd.Initialize(Other,OFirst,OLast,Precision::PConfusion());
754
755 for (Standard_Integer i = 1; i < NCtrl; i++) { //szv#4:S4163:12Mar99 was bug
756 Standard_Real rprm = ((NCtrl-i)*First + i*Last)/NCtrl;
757 gp_Pnt pref = CRef.Value(rprm);
758 Standard_Real oprm = ((NCtrl-i)*OFirst + i*OLast)/NCtrl;
759 gp_Pnt pother = Other.Value(oprm);
760
761 refd.Perform(pother,rprm);
762 if ( ! refd.IsDone() ) OK = Standard_False;
763 else if ( dev2 < refd.SquareDistance() ) {dev2 = refd.SquareDistance(); dev = sqrt (dev2);}
764
765 otherd.Perform(pref,oprm);
766 if ( ! otherd.IsDone() ) OK = Standard_False;
767 else if ( dev2 < otherd.SquareDistance() ) {dev2 = otherd.SquareDistance(); dev = sqrt (dev2);}
768 }
769 }
770 dev *= 1.00001;//ims007 entity 8067 edge 3; 1e-07USA60022 (4255, 4-th edge) SA_Check and BRepCh find distinct points001; // ensure that dev*dev >= dev2
771
772 return OK;
773}
774
775
776//=======================================================================
777//function : CheckSameParameter
778//purpose :
779//=======================================================================
780
781Standard_Boolean ShapeAnalysis_Edge::CheckSameParameter (const TopoDS_Edge& edge,
782 Standard_Real& maxdev,
783 const Standard_Integer NbControl)
784{
785 myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
786 if (BRep_Tool::Degenerated (edge)) return Standard_False;
787
788 maxdev = 0;
789
790 Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&edge.TShape());
791 Standard_Boolean SameParameter = TE->SameParameter();
792
793 GeomAdaptor_Curve AC3d;
794
795 // find 3d curve
796 BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
797 for ( ; itcr.More(); itcr.Next() ) {
798 Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
799 if ( GC.IsNull() || ! GC->IsCurve3D() ) continue;
800 Handle(Geom_Curve) C3d = GC->Curve3D();
801 if ( C3d.IsNull() ) continue; //:s1 abv 22 Apr 99: PRO7226 #489490
802 TopLoc_Location loc = GC->Location();
803 if ( ! loc.IsIdentity() )
804 C3d = Handle(Geom_Curve)::DownCast ( C3d->Transformed ( loc ) );
805 else C3d = Handle(Geom_Curve)::DownCast ( C3d->Copy() ); //:s4 abv 26 Apr 99: sim6049.igs 21677: necessary to get True SP (!!?)
806 Standard_Real First, Last;
807 GC->Range ( First, Last );
808 AC3d.Load ( C3d, First, Last );
809 break;
810 }
811
812 if ( ! itcr.More() ) {
813 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL1 );
814 return Standard_False;
815 }
816
817 // iterate on pcurves
818 itcr.Initialize ( TE->Curves() );
819 for ( ; itcr.More(); itcr.Next() ) {
820 Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
821 if ( GC.IsNull() || ! GC->IsCurveOnSurface() ) continue;
822
823 Standard_Real f, l;
824 GC->Range ( f, l );
825 Handle(Geom_Surface) Su = GC->Surface();
826 TopLoc_Location loc = GC->Location();
827 if (!loc.IsIdentity())
828 Su = Handle(Geom_Surface)::DownCast ( Su->Transformed ( loc ) );
829 Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(Su);
830
831 Handle(Geom2d_Curve) PC = GC->PCurve();
832 Handle(Geom2dAdaptor_HCurve) GHPC = new Geom2dAdaptor_HCurve(PC,f,l);
833 //Adaptor3d_CurveOnSurface ACS(GHPC,GAHS);
834 Adaptor3d_CurveOnSurface ACS;
543a9964 835 ACS.Load(GHPC, GAHS);
7fd59977 836 if ( ! ComputeDeviation ( AC3d, ACS, SameParameter, maxdev, NbControl-1 ) ) {
837 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL2 );
838 }
839
840 if ( GC->IsCurveOnClosedSurface() ) {
841 GHPC->ChangeCurve2d().Load ( GC->PCurve2(), f, l ); // same bounds
543a9964 842 ACS.Load(GHPC, GAHS); // sans doute inutile
7fd59977 843 if ( ! ComputeDeviation ( AC3d, ACS, SameParameter, maxdev, NbControl-1 ) ) {
844 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL2 );
845 }
846 }
847 }
848
849 if ( maxdev > TE->Tolerance() )
850 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 );
851 if ( ! SameParameter )
852 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 );
853
854 return Status ( ShapeExtend_DONE );
855}
856
857
858//=======================================================================
859//function : IsOverlapPartEdges
860//purpose :
861//=======================================================================
862
863static Standard_Boolean IsOverlapPartEdges(const TopoDS_Edge& theFirstEdge,
864 const TopoDS_Edge& theSecEdge,
865 const Standard_Real& theTolerance,
866 const Standard_Real& theStep,
867 const Standard_Real& theStartLength,
868 const Standard_Real& theEndLenght)
869{
870 TColStd_SequenceOfInteger aSeqIntervals;
871 BRepAdaptor_Curve aAdCurve1(theFirstEdge);
872
873 BRepExtrema_DistShapeShape aMinDist;
874 aMinDist.LoadS1(theSecEdge);
875
876 for(Standard_Real aS = theStartLength; aS <= theEndLenght; aS+=theStep/2) {
877
878 gp_Pnt aPoint;
879 if(aS <= Precision::Confusion()) {
880 TopoDS_Vertex V1 = TopExp::FirstVertex(theFirstEdge,Standard_True);
881 aPoint = BRep_Tool::Pnt(V1);
882 }
883 else {
884 GCPnts_AbscissaPoint aAbsPoint(Precision::Confusion(),aAdCurve1,aS,aAdCurve1.FirstParameter());
885 if(aAbsPoint.IsDone())
886 aAdCurve1.D0(aAbsPoint.Parameter(),aPoint);
887 else continue;
888 }
889 BRep_Builder aB;
890 TopoDS_Vertex aV;
891 aB.MakeVertex(aV,aPoint,Precision::Confusion());
892 aMinDist.LoadS2(aV);
893 aMinDist.Perform();
894 if( aMinDist.IsDone() && aMinDist.Value() >= theTolerance)
895 return Standard_False;
896 }
897 return Standard_True;
898}
899
900
901//=======================================================================
902//function : CheckOverlapping
903//purpose :
904//=======================================================================
905
906Standard_Boolean ShapeAnalysis_Edge::CheckOverlapping(const TopoDS_Edge& theEdge1,
907 const TopoDS_Edge& theEdge2,
908 Standard_Real& theTolOverlap,
909 const Standard_Real theDomainDist)
910{
911 Standard_Boolean isOverlap = Standard_False;
912 BRepAdaptor_Curve aAdCurve1(theEdge1);
913 Standard_Real aLength1 = GCPnts_AbscissaPoint::Length (aAdCurve1);
914 BRepAdaptor_Curve aAdCurve2(theEdge2);
915 Standard_Real aLength2 = GCPnts_AbscissaPoint::Length (aAdCurve2);
916 TopoDS_Edge aFirstEdge = (aLength1 >= aLength2 ? theEdge2: theEdge1);
917 TopoDS_Edge aSecEdge = (aLength1 >= aLength2 ? theEdge1: theEdge2);
918 Standard_Real aLength = Min(aLength1,aLength2);
919
920 //check overalpping between edges on whole edges
921 Standard_Real aStep = Min(aLength1,aLength2)/2;
922 isOverlap = IsOverlapPartEdges(aFirstEdge,aSecEdge,theTolOverlap,aStep,0.,Min(aLength1,aLength2));
923
924 if(isOverlap) {
925 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE3);
926 return isOverlap;
927 }
928 if(theDomainDist ==0.0)
929 return isOverlap;
930
931 //check overalpping between edges on segment with length less than theDomainDist
932
933 Standard_Real aDomainTol = (theDomainDist > Min( aLength1,aLength2) ? Min( aLength1,aLength2) :theDomainDist);
934 BRepExtrema_DistShapeShape aMinDist(aFirstEdge,aSecEdge,theTolOverlap);
935 Standard_Real aresTol = theTolOverlap;
936 if(aMinDist.IsDone()) {
937 aresTol = aMinDist.Value();
938 if(aresTol >= theTolOverlap) return Standard_False;
939 Standard_Integer NbSol = aMinDist.NbSolution();
940 for(Standard_Integer i =1; i<= NbSol && !isOverlap; i++) {
941 BRepExtrema_SupportType aType1 = aMinDist.SupportTypeShape1(i);
942 Standard_Real aEndLength, aStartLength, aLengthP;
943 if(aType1 == BRepExtrema_IsVertex) {
944 TopoDS_Shape aSupportShape1 = aMinDist.SupportOnShape1(i);
945 TopoDS_Vertex aV1,aV2;
946 TopExp::Vertices (aFirstEdge, aV1, aV2, Standard_True);
947 if( aV1.IsSame(aSupportShape1))
948 aLengthP = 0.0;
949 else
950 aLengthP =aLength;
951 }
952 else if(aType1 == BRepExtrema_IsOnEdge) {
953 Standard_Real aParam1, aFirst, aLast;
954 aMinDist.ParOnEdgeS1 ( i, aParam1 );
955 BRep_Tool::Range(aFirstEdge,aFirst,aLast);
956 BRepAdaptor_Curve anAdaptor(aFirstEdge);
957 aLengthP = GCPnts_AbscissaPoint::Length(anAdaptor,aFirst,aParam1);
958 }
959 else continue;
960 aStartLength = aLengthP - aDomainTol/2;
961 if( aStartLength <0.0) {
962 aStartLength =0;
963 aEndLength = aDomainTol;
964 }
965 aEndLength = aLengthP + aDomainTol/2;
966 if(aEndLength > aLength) {
967 aEndLength = aLength;
968 aStartLength = aEndLength - aDomainTol;
969 }
970 aStep = (aEndLength - aStartLength)/5;
971 isOverlap = (IsOverlapPartEdges(aFirstEdge,aSecEdge,theTolOverlap,aStep,aStartLength,aEndLength));
972 }
973 }
974 if(isOverlap)
975 myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE4);
976
977 theTolOverlap = aresTol;
978 return isOverlap;
979}