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