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