0030686: Visualization, SelectMgr_ViewerSelector - sorting issues of transformation...
[occt.git] / src / BRepFill / BRepFill_MultiLine.cxx
CommitLineData
b311480e 1// Created on: 1994-11-14
2// Created by: Bruno DUMORTIER
3// Copyright (c) 1994-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 8// This library is free software; you can redistribute it and/or modify it under
9// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 10// by the Free Software Foundation, with special exception defined in the file
11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12// distribution for complete text of the license and disclaimer of any warranty.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
368cdde6 17#include <BRepFill_MultiLine.hxx>
7fd59977 18
19#include <BRepIntCurveSurface_Inter.hxx>
20#include <gp.hxx>
21#include <gp_Lin.hxx>
22#include <gp_Ax3.hxx>
23#include <gp_Lin2d.hxx>
24#include <gp_Circ2d.hxx>
25#include <Precision.hxx>
26#include <BRep_Tool.hxx>
27#include <Geom_Line.hxx>
28#include <Geom_Plane.hxx>
29#include <Geom_TrimmedCurve.hxx>
30#include <Geom2d_TrimmedCurve.hxx>
31#include <Geom_Surface.hxx>
32#include <Geom_RectangularTrimmedSurface.hxx>
33#include <Geom2d_Line.hxx>
34#include <GeomProjLib.hxx>
35#include <Geom2dAPI_ProjectPointOnCurve.hxx>
36#include <Geom2dInt_GInter.hxx>
37#include <IntRes2d_IntersectionPoint.hxx>
38#include <Standard_ConstructionError.hxx>
39#include <IntRes2d_IntersectionSegment.hxx>
40#include <TopExp_Explorer.hxx>
41#include <TopoDS.hxx>
42#include <ElCLib.hxx>
004e8466 43#include <GeomAdaptor_Curve.hxx>
7fd59977 44
45#include <GeomAdaptor_Surface.hxx>
46#include <GeomAbs_SurfaceType.hxx>
47
48#ifdef DRAW
49#include <DrawTrSurf.hxx>
7fd59977 50static Standard_Boolean AffichCurve = Standard_False;
51static Standard_Integer NbProj = 1;
52#endif
1896126e 53
7fd59977 54//POP pour NT
55#include <stdio.h>
56
57//=======================================================================
58//function : isIsoU
59//purpose :
60//=======================================================================
61
62static Standard_Boolean isIsoU(const TopoDS_Face& Face,
df573a26 63 const TopoDS_Edge& Edge )
7fd59977 64{
65 Handle(Geom2d_Curve) C;
66 Handle(Geom2d_Line) Li;
67 Standard_Real f,l;
68
69 C = BRep_Tool::CurveOnSurface(Edge,Face, f, l);
70 if ( C.IsNull()) {
9775fa61 71 throw Standard_ConstructionError("BRepFill_MultiLine : Edge without PCurve");
7fd59977 72 }
df573a26 73
7fd59977 74 gp_Dir2d D = C->DN(f,1);
75
76 if (Abs(D.Dot(gp::DX2d())) < Abs(D.Dot(gp::DY2d())))
77 return Standard_True;
78 else
79 return Standard_False;
80}
81
82
7fd59977 83//=======================================================================
84//function : BRepFill_MultiLine
85//purpose :
86//=======================================================================
87
88BRepFill_MultiLine::BRepFill_MultiLine()
89{
368cdde6 90 myNbPnt2d = 2;
91 myNbPnt = 1;
7fd59977 92}
93
94
95//=======================================================================
96//function : BRepFill_MultiLine
97//purpose :
98//=======================================================================
99
100BRepFill_MultiLine::BRepFill_MultiLine(const TopoDS_Face& Face1,
df573a26 101 const TopoDS_Face& Face2,
102 const TopoDS_Edge& Edge1,
103 const TopoDS_Edge& Edge2,
104 const Standard_Boolean Inv1,
105 const Standard_Boolean Inv2,
106 const Handle(Geom2d_Curve)& Bissec)
107 : myFace1(Face1 ),
368cdde6 108 myFace2(Face2 ),
109 myBis (Bissec),
110 myKPart(0)
7fd59977 111{
df573a26 112 //
113 const Standard_Real mult = 5.;
114 const Standard_Real eps = mult * Precision::Confusion();
115 //
368cdde6 116 myNbPnt2d = 2;
117 myNbPnt = 1;
118
7fd59977 119 // eval if myedges are IsoU or not
120 myIsoU1 = isIsoU(Face1, Edge1);
121 myIsoU2 = isIsoU(Face2, Edge2);
122
123 // eval myU1, myV1, myU2, myV2;
124 Handle(Geom_Plane) RefPlane;
125 Handle(Geom_Plane) BasisPlane = new Geom_Plane(0.,0.,1.,0.);
126 TopLoc_Location L;
127
128 TopExp_Explorer Exp;
1d47d8d0 129 Standard_Real Umin = 0.,Vmin = 0.,Umax = 0.,Vmax = 0.,U,V;
7fd59977 130 gp_Pnt2d P1,P2;
131 gp_Vec DZ;
132 gp_Pnt P;
133
134 // Result on Face1
135 Standard_Boolean First = Standard_True;
136 for (Exp.Init(myFace1,TopAbs_EDGE);Exp.More(); Exp.Next()) {
137 TopoDS_Edge CurEdge = TopoDS::Edge(Exp.Current());
138 BRep_Tool::UVPoints(CurEdge,myFace1,P1,P2);
139 if ( First) {
140 First = Standard_False;
141 Umin = Min(P1.X(),P2.X());
142 Umax = Max(P1.X(),P2.X());
df573a26 143
7fd59977 144 Vmin = Min(P1.Y(),P2.Y());
145 Vmax = Max(P1.Y(),P2.Y());
146 }
147 else {
148 U = Min(P1.X(),P2.X());
149 Umin = Min(Umin,U);
150 U = Max(P1.X(),P2.X());
151 Umax = Max(Umax,U);
152
153 V = Min(P1.Y(),P2.Y());
154 Vmin = Min(Vmin,V);
155 V = Max(P1.Y(),P2.Y());
156 Vmax = Max(Vmax,V);
157 }
158 }
7fd59977 159
0d969553 160 // return isos in their domain of restriction.
7fd59977 161 Handle(Geom_Curve) UU1, UU2, VV1, VV2;
162 Handle(Geom_Surface) S;
163 S = BRep_Tool::Surface(myFace1,L);
164 if (!L.IsIdentity())
165 S = Handle(Geom_Surface)::DownCast(S->Transformed(L.Transformation()));
166
167 if ( myIsoU1) {
168 if (!BRep_Tool::Degenerated(Edge1) && !Inv1) {
169 UU1 = S->UIso(Umin);
170 GeomAdaptor_Curve Dummy(UU1);
171 if (Dummy.GetType() == GeomAbs_Circle &&
df573a26 172 Dummy.Circle().Radius() < eps) {
173 UU1 = S->UIso(Umax);
7fd59977 174 }
175 }
176 else {
177 UU1 = S->UIso(Umax);
178 GeomAdaptor_Curve Dummy(UU1);
179 if (Dummy.GetType() == GeomAbs_Circle &&
df573a26 180 Dummy.Circle().Radius() < eps) {
181 UU1 = S->UIso(Umin);
7fd59977 182 }
183 }
184 VV1 = S->VIso(Vmin);
185 }
186 else {
187 if (!BRep_Tool::Degenerated(Edge1) && !Inv1) {
188 UU1 = S->VIso(Vmin);
189 GeomAdaptor_Curve Dummy(UU1);
190 if (Dummy.GetType() == GeomAbs_Circle &&
df573a26 191 Dummy.Circle().Radius() < eps) {
192 UU1 = S->VIso(Vmax);
7fd59977 193 }
194 }
195 else {
196 UU1 = S->VIso(Vmax);
197 GeomAdaptor_Curve Dummy(UU1);
198 if (Dummy.GetType() == GeomAbs_Circle &&
df573a26 199 Dummy.Circle().Radius() < eps) {
200 UU1 = S->VIso(Vmin);
7fd59977 201 }
202 }
203 VV1 = S->UIso(Umin);
204 }
205
206 if ( myIsoU1) {
207 Standard_Real dummyUmin = Umin, dummyUmax = Umax;
208 Umin = Vmin;
209 Umax = Vmax;
210 Vmin = dummyUmin;
211 Vmax = dummyUmax;
212 }
213
0d969553 214 // try duplication
7fd59977 215 GeomAdaptor_Surface GAS1(S);
216 GeomAbs_SurfaceType Type1 = GAS1.GetType();
217
218 if ( UU1->IsPeriodic()) {
219 ElCLib::AdjustPeriodic(UU1->FirstParameter(),
df573a26 220 UU1->LastParameter(),
221 Precision::PConfusion(),
222 Umin, Umax);
7fd59977 223 }
224 if ( VV1->IsPeriodic()) {
225 ElCLib::AdjustPeriodic(VV1->FirstParameter(),
df573a26 226 VV1->LastParameter(),
227 Precision::PConfusion(),
228 Vmin, Vmax);
7fd59977 229 }
0d969553 230 // end try duplication
7fd59977 231
232 myU1 = Geom2dAdaptor_Curve(GeomProjLib::Curve2d(UU1, BasisPlane),
df573a26 233 Umin, Umax);
7fd59977 234
235 UU1->D1(Umin, P, DZ);
236 RefPlane = new Geom_Plane(gp_Ax3(P,DZ,gp::DZ()));
237
238 myV1 = Geom2dAdaptor_Curve(GeomProjLib::Curve2d(VV1, RefPlane),
df573a26 239 Vmin, Vmax);
7fd59977 240
241
242 First = Standard_True;
243 for (Exp.Init(myFace2,TopAbs_EDGE);Exp.More(); Exp.Next()) {
244 TopoDS_Edge CurEdge = TopoDS::Edge(Exp.Current());
245 BRep_Tool::UVPoints(CurEdge,myFace2,P1,P2);
246 if ( First) {
247 First = Standard_False;
248 Umin = Min(P1.X(),P2.X());
249 Umax = Max(P1.X(),P2.X());
df573a26 250
7fd59977 251 Vmin = Min(P1.Y(),P2.Y());
252 Vmax = Max(P1.Y(),P2.Y());
253 }
254 else {
255 U = Min(P1.X(),P2.X());
256 Umin = Min(Umin,U);
257 U = Max(P1.X(),P2.X());
258 Umax = Max(Umax,U);
259
260 V = Min(P1.Y(),P2.Y());
261 Vmin = Min(Vmin,V);
262 V = Max(P1.Y(),P2.Y());
263 Vmax = Max(Vmax,V);
264 }
265 }
266
0d969553 267 // return isos in their domain of restriction.
7fd59977 268 S = BRep_Tool::Surface(myFace2,L);
269
270 if (!L.IsIdentity())
271 S = Handle(Geom_Surface)::DownCast(S->Transformed(L.Transformation()));
272
273 if ( myIsoU2) {
274 if (!BRep_Tool::Degenerated(Edge2) && !Inv2) {
275 UU2 = S->UIso(Umin);
276 GeomAdaptor_Curve Dummy(UU2);
277 if (Dummy.GetType() == GeomAbs_Circle &&
df573a26 278 Dummy.Circle().Radius() < eps) {
279 UU2 = S->UIso(Umax);
7fd59977 280 }
281 }
282 else {
283 UU2 = S->UIso(Umax);
284 GeomAdaptor_Curve Dummy(UU2);
285 if (Dummy.GetType() == GeomAbs_Circle &&
df573a26 286 Dummy.Circle().Radius() < eps) {
287 UU2 = S->UIso(Umin);
7fd59977 288 }
289 }
290 VV2 = S->VIso(Vmin);
291 }
292 else {
293 if (!BRep_Tool::Degenerated(Edge2) && !Inv2) {
294 UU2 = S->VIso(Vmin);
295 GeomAdaptor_Curve Dummy(UU2);
296 if (Dummy.GetType() == GeomAbs_Circle &&
df573a26 297 Dummy.Circle().Radius() < eps) {
298 UU2 = S->VIso(Vmax);
7fd59977 299 }
300 }
301 else {
302 UU2 = S->VIso(Vmax);
303 GeomAdaptor_Curve Dummy(UU2);
304 if (Dummy.GetType() == GeomAbs_Circle &&
df573a26 305 Dummy.Circle().Radius() < eps) {
306 UU2 = S->VIso(Vmin);
7fd59977 307 }
308 }
309 VV2 = S->UIso(Umin);
310 }
df573a26 311
7fd59977 312 if ( myIsoU2) {
313 Standard_Real dummyUmin = Umin, dummyUmax = Umax;
314 Umin = Vmin;
315 Umax = Vmax;
316 Vmin = dummyUmin;
317 Vmax = dummyUmax;
318 }
319
0d969553 320 // try duplication
7fd59977 321 GeomAdaptor_Surface GAS2(S);
322 GeomAbs_SurfaceType Type2 = GAS2.GetType();
323
324 if ( UU2->IsPeriodic()) {
325 ElCLib::AdjustPeriodic(UU2->FirstParameter(),
df573a26 326 UU2->LastParameter(),
327 Precision::PConfusion(),
328 Umin, Umax);
7fd59977 329 }
330 if ( VV2->IsPeriodic()) {
331 ElCLib::AdjustPeriodic(VV2->FirstParameter(),
df573a26 332 VV2->LastParameter(),
333 Precision::PConfusion(),
334 Vmin, Vmax);
7fd59977 335 }
0d969553 336 // end try duplication
7fd59977 337
338 myU2 = Geom2dAdaptor_Curve(GeomProjLib::Curve2d(UU2, BasisPlane),
df573a26 339 Umin, Umax);
7fd59977 340
341 UU2->D1(Umin, P, DZ);
342 RefPlane = new Geom_Plane(gp_Ax3(P,DZ,gp::DZ()));
343 myV2 = Geom2dAdaptor_Curve(GeomProjLib::Curve2d(VV2, RefPlane),
df573a26 344 Vmin, Vmax);
7fd59977 345
346 // eval if in a particular case.
0d969553
Y
347 // Particular case if :
348 // 1) - Straight Bissectrice
349 // - Bissectrice orthogonal to the base element.
350 // ==> Iso on 2 faces.
351 // 2) - Straight Bissectrice
352 // - 2 surfaces are planes.
7fd59977 353 myCont = GeomAbs_C0;
354
355 if ( myBis.GetType() == GeomAbs_Line) {
356 Standard_Real DeltaU = myBis.LastParameter() - myBis.FirstParameter();
51740958 357 gp_Pnt2d aPnt1 = ValueOnF1(myBis.FirstParameter() + 0.1*DeltaU);
358 gp_Pnt2d aPnt2 = ValueOnF1(myBis.FirstParameter() + 0.9*DeltaU);
7fd59977 359 if ( myIsoU1) {
df573a26 360 if ( Abs(aPnt1.Y() - aPnt2.Y()) < eps)
361 myKPart = 1;
7fd59977 362 }
363 else {
df573a26 364 if ( Abs(aPnt1.X() - aPnt2.X()) < eps)
365 myKPart = 1;
7fd59977 366 }
df573a26 367
7fd59977 368 if ( myKPart == 1)
369 myCont = GeomAbs_G1;
370
371 if ( (Type1 == GeomAbs_Plane) && (Type2 == GeomAbs_Plane)) {
372 myKPart = 2;
373 }
374 }
375}
376
377
378//=======================================================================
379//function : IsParticularCase
380//purpose :
381//=======================================================================
382
383Standard_Boolean BRepFill_MultiLine::IsParticularCase() const
384{
385 return ( myKPart != 0);
386}
387
388
389//=======================================================================
390//function : Curves
391//purpose :
392//=======================================================================
393
394void BRepFill_MultiLine::Curves(Handle(Geom_Curve)& Curve,
df573a26 395 Handle(Geom2d_Curve)& PCurve1,
396 Handle(Geom2d_Curve)& PCurve2) const
7fd59977 397{
398 if ( myKPart == 1) {
399 gp_Pnt2d P1,P2,PMil;
400 Standard_Real f,l;
401
402 P1 = ValueOnF1(myBis.FirstParameter());
403 P2 = ValueOnF1(myBis.LastParameter());
404
0d969553
Y
405 // find value of the with medium point
406 // the ends can be degenerated points.
7fd59977 407
408 PMil = ValueOnF1(0.5*(myBis.FirstParameter() + myBis.LastParameter()));
df573a26 409
7fd59977 410 TopLoc_Location L;
411 Handle(Geom_Surface) S = BRep_Tool::Surface(myFace1,L);
412 if (!L.IsIdentity())
413 S = Handle(Geom_Surface)::DownCast(S->Transformed(L.Transformation()));
df573a26 414
7fd59977 415 Standard_Boolean Sens;
416 if ( !myIsoU1) {
417 Curve = S->UIso(PMil.X());
418 Sens = P1.Y() < P2.Y();
419 if ( Sens)
df573a26 420 Curve = new Geom_TrimmedCurve(Curve, P1.Y(), P2.Y(), Sens);
7fd59977 421 else
df573a26 422 Curve = new Geom_TrimmedCurve(Curve, P2.Y(), P1.Y(), Sens);
423
7fd59977 424 f = Curve->FirstParameter();
425 l = Curve->LastParameter();
426 if ( Sens)
df573a26 427 PCurve1 = new Geom2d_Line(gp_Pnt2d(PMil.X(),P1.Y() - f), gp::DY2d());
7fd59977 428 else
df573a26 429 PCurve1 = new Geom2d_Line(gp_Pnt2d(PMil.X(),P1.Y() + f),-gp::DY2d());
7fd59977 430 PCurve1 = new Geom2d_TrimmedCurve( PCurve1 ,f ,l);
431 }
432 else {
433 Curve = S->VIso(PMil.Y());
434 Sens = P1.X() < P2.X();
435 if (Sens)
df573a26 436 Curve = new Geom_TrimmedCurve(Curve, P1.X(), P2.X(), Sens);
7fd59977 437 else
df573a26 438 Curve = new Geom_TrimmedCurve(Curve, P2.X(), P1.X(), Sens);
439
7fd59977 440 f = Curve->FirstParameter();
441 l = Curve->LastParameter();
442 if ( Sens)
df573a26 443 PCurve1 = new Geom2d_Line(gp_Pnt2d(P1.X() - f,PMil.Y()), gp::DX2d());
7fd59977 444 else
df573a26 445 PCurve1 = new Geom2d_Line(gp_Pnt2d(P1.X() + f,PMil.Y()), -gp::DX2d());
7fd59977 446 PCurve1 = new Geom2d_TrimmedCurve( PCurve1 ,f ,l);
447 }
df573a26 448
7fd59977 449 P1 = ValueOnF2(myBis.FirstParameter());
450 P2 = ValueOnF2(myBis.LastParameter());
451 PMil = ValueOnF2(0.5*(myBis.FirstParameter() + myBis.LastParameter()));
df573a26 452
7fd59977 453 if (!myIsoU2) {
454 Sens = P1.Y() < P2.Y();
455 if ( Sens)
df573a26 456 PCurve2 = new Geom2d_Line(gp_Pnt2d(PMil.X(),(P1.Y() - f)), gp::DY2d());
7fd59977 457 else
df573a26 458 PCurve2 = new Geom2d_Line(gp_Pnt2d(PMil.X(),(P1.Y() + f)), -gp::DY2d());
7fd59977 459 }
460 else {
461 Sens = P1.X() < P2.X();
462 if ( Sens)
df573a26 463 PCurve2 = new Geom2d_Line(gp_Pnt2d(P1.X() - f ,PMil.Y()), gp::DX2d());
7fd59977 464 else
df573a26 465 PCurve2 = new Geom2d_Line(gp_Pnt2d(P1.X() + f ,PMil.Y()), -gp::DX2d());
7fd59977 466 }
467 PCurve2 = new Geom2d_TrimmedCurve( PCurve2 ,f ,l);
468 }
469 else if ( myKPart == 2) {
470 TopLoc_Location L;
df573a26 471
7fd59977 472 Handle(Geom_Surface) S = BRep_Tool::Surface(myFace1,L);
473 if (!L.IsIdentity())
474 S = Handle(Geom_Surface)::DownCast(S->Transformed(L.Transformation()));
df573a26 475
7fd59977 476 if (S->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
477 S = Handle(Geom_RectangularTrimmedSurface)::DownCast(S)->BasisSurface();
478
479 Handle(Geom_Plane) Plane = Handle(Geom_Plane)::DownCast(S);
480 // eval the 3d curve corresponding to the bissectrice.
481 gp_Pnt2d P = myBis.Line().Location();
482 gp_Dir2d D = myBis.Line().Direction();
483 Handle(Geom_Line) Line = new Geom_Line(gp_Pnt(P.X(),P.Y(),0.),
df573a26 484 gp_Dir(D.X(),D.Y(),0.) );
7fd59977 485 Handle(Geom_TrimmedCurve) TLine =
486 new Geom_TrimmedCurve(Line, myBis.FirstParameter(),
df573a26 487 myBis.LastParameter());
7fd59977 488 Curve = GeomProjLib::ProjectOnPlane(TLine, Plane,
df573a26 489 gp::DZ(), Standard_False);
7fd59977 490
491#ifdef DRAW
492 if ( AffichCurve) {
1896126e 493 char name[100];
7fd59977 494 sprintf(name,"C2_%d",NbProj);
495 DrawTrSurf::Set(name,TLine);
496 sprintf(name,"C3_%d",NbProj);
497 DrawTrSurf::Set(name,Curve);
498 sprintf(name,"SS_%d",NbProj);
499 DrawTrSurf::Set(name,Plane);
500 NbProj++;
501 }
502#endif
503
504 // eval PCurve1
505 PCurve1 = GeomProjLib::Curve2d(Curve,Plane);
df573a26 506
7fd59977 507 // eval PCurve2
508 S = BRep_Tool::Surface(myFace2,L);
509 if (!L.IsIdentity())
510 S = Handle(Geom_Surface)::DownCast(S->Transformed(L.Transformation()));
511 if (S->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
512 S = Handle(Geom_RectangularTrimmedSurface)::DownCast(S)->BasisSurface();
513 Plane = Handle(Geom_Plane)::DownCast(S);
514 PCurve2 = GeomProjLib::Curve2d(Curve,Plane);
515 }
516}
517
518
519//=======================================================================
520//function : FirstParameter
521//purpose :
522//=======================================================================
523
524Standard_Real BRepFill_MultiLine::FirstParameter() const
525{
526 return myBis.FirstParameter();
527}
528
529
530//=======================================================================
531//function : LastParameter
532//purpose :
533//=======================================================================
534
535Standard_Real BRepFill_MultiLine::LastParameter() const
536{
537 return myBis.LastParameter();
538}
539
540
541//=======================================================================
542//function : Value
543//purpose :
544//=======================================================================
545
546gp_Pnt BRepFill_MultiLine::Value(const Standard_Real U) const
547{
548 Handle(Geom_Surface) S;
549 TopLoc_Location L;
550
551 S = BRep_Tool::Surface(myFace1,L);
552
553 gp_Pnt2d P2d = ValueOnF1(U);
554
555 gp_Pnt P3d = S->Value(P2d.X(), P2d.Y());
556 P3d.Transform(L.Transformation());
557
558 return P3d;
559}
560
561
562//=======================================================================
563//function : ValueOnFace
564//purpose :
565//=======================================================================
566
567static gp_Pnt2d ValueOnFace(const Standard_Real U,
df573a26 568 const Geom2dAdaptor_Curve& TheBis,
569 const Geom2dAdaptor_Curve& TheU,
570 const Geom2dAdaptor_Curve& TheV,
571 const Standard_Boolean IsIsoU)
7fd59977 572{
573 gp_Pnt2d P = TheBis.Value(U);
574
575 Geom2dAPI_ProjectPointOnCurve Ext(P,TheU.Curve(),
df573a26 576 TheU.FirstParameter(),
577 TheU.LastParameter());
7fd59977 578#ifdef DRAW
579 if (AffichCurve) {
580 char* TheUname = "TheU";
581 char* PP1name = "PP1";
582 DrawTrSurf::Set(TheUname,TheU.Curve());
583 DrawTrSurf::Set(PP1name,P);
df573a26 584 // DrawTrSurf::Set("TheU",TheU.Curve());
585 // DrawTrSurf::Set("PP1",P);
7fd59977 586 }
587#endif
df573a26 588 //
589 const Standard_Real mult = 5.;
590 const Standard_Real eps = mult * Precision::Confusion();
591 //
7fd59977 592 Standard_Real UU =0., Dist = Precision::Infinite(), D1, D2;
593
c29a9290 594 if ( Ext.NbPoints() != 0 ) {
7fd59977 595 UU = Ext.LowerDistanceParameter();
596 Dist = Ext.LowerDistance();
597 }
0d969553 598 // Control with `ends`
7fd59977 599 D1 = P.Distance(TheU.Value(TheU.FirstParameter()));
600 D2 = P.Distance(TheU.Value(TheU.LastParameter()));
601
df573a26 602 if (D1 < Dist || D2 < Dist || Abs(D1 - Dist) < eps || Abs(D2 - Dist) < eps) {
603 if ( Abs( D1 - D2) < eps) {
7fd59977 604 if ( TheU.GetType() == GeomAbs_Circle) {
df573a26 605 gp_Vec2d Axis = TheU.Circle().XAxis().Direction();
606 gp_Vec2d D12d = TheBis.DN(TheBis.FirstParameter(),1);
607 Standard_Real Ang = Axis.Angle(D12d);
608 if ( !TheU.Circle().IsDirect()) Ang = -Ang;
609 UU = ElCLib::InPeriod( Ang, TheU.FirstParameter(),
610 TheU.FirstParameter() + 2*M_PI);
611 Dist = TheU.Circle().Radius();
7fd59977 612 }
613 else {
0797d9d3 614#ifdef OCCT_DEBUG
df573a26 615 cout << "MultiLine : D1 = D2 and the Curve is not a circle" << endl;
616 cout << " ---> ValueOnFace failed at parameter U = " << U << endl;
7fd59977 617#endif
9775fa61 618 throw Standard_ConstructionError("BRepFill_MultiLine: ValueOnFace");
7fd59977 619 }
620 }
621 else if ( D1 < D2) {
622 Dist = D1;
623 UU = TheU.FirstParameter();
624 }
625 else {
626 Dist = D2;
627 UU = TheU.LastParameter();
628 }
629 }
630
df573a26 631 const Standard_Real Tol = Precision::Confusion();
7fd59977 632 Standard_Real VV;
633
634 gp_Pnt2d PF = TheV.Value(TheV.FirstParameter());
635 gp_Pnt2d PL = TheV.Value(TheV.LastParameter());
df573a26 636
7fd59977 637 if (Abs(Dist - Abs(PF.Y())) < Tol) {
638 VV = TheV.FirstParameter();
639 }
640 else if (Abs(Dist - Abs(PL.Y())) < Tol) {
641 VV = TheV.LastParameter();
642 }
643 else {
0d969553 644 // test if the curve is at the side `negative Y`.
7fd59977 645 if ( Min( PF.Y(),PL.Y()) < -Tol) Dist = -Dist;
df573a26 646
7fd59977 647 Handle(Geom2d_Line) Line
648 = new Geom2d_Line(gp_Pnt2d(0., Dist), gp::DX2d());
df573a26 649
7fd59977 650#ifdef DRAW
651 if (AffichCurve) {
652 static Standard_CString aTheV = "TheV" ;
653 DrawTrSurf::Set(aTheV,TheV.Curve());
654 static Standard_CString aLINF1 = "LINF1" ;
655 DrawTrSurf::Set(aLINF1,Line);
656 }
657#endif
df573a26 658
7fd59977 659 Geom2dAdaptor_Curve Cu1 = TheV;
660 Geom2dAdaptor_Curve Cu2( Line);
df573a26 661
7fd59977 662 Standard_Real TolConf = 0.;
663
664 Geom2dInt_GInter Intersector(Cu1,Cu2,TolConf,Tol);
665
666 if ( !Intersector.IsDone()) {
0797d9d3 667#ifdef OCCT_DEBUG
7fd59977 668 cout << "Intersector not done" << endl;
669 cout << " ---> ValueonFace failed at parameter U = " << U << endl;
670#endif
671 return gp_Pnt2d(0.,0.);
672 }
673 else {
674 if ( Intersector.NbPoints() > 0) {
df573a26 675 VV = Intersector.Point(1).ParamOnFirst();
7fd59977 676 }
677 else if ( Intersector.NbSegments() > 0) {
df573a26 678 IntRes2d_IntersectionSegment Seg = Intersector.Segment(1);
679 Standard_Real VS1 = Seg.FirstPoint().ParamOnFirst();
680 Standard_Real VS2 = Seg.LastPoint().ParamOnFirst();
681 gp_Pnt2d PS1 = TheV.Value(VS1);
682 gp_Pnt2d PS2 = TheV.Value(VS2);
683 Standard_Real Alp = (Dist - PS1.Y())/(PS2.Y() - PS1.Y());
684 VV = Alp*(VS2 - VS1) + VS1;
7fd59977 685 }
686 else {
0797d9d3 687#ifdef OCCT_DEBUG
df573a26 688 cout << "Intersector done, but no points found" << endl;
689 cout << " ---> ValueonFace failed at parameter U = " << U << endl;
7fd59977 690#endif
df573a26 691 if (Abs(Dist - PL.Y()) < Abs(Dist - PF.Y()))
692 VV = TheV.LastParameter();
693 else
694 VV = TheV.FirstParameter();
7fd59977 695 }
696 }
697 }
698
699 if ( IsIsoU)
700 return gp_Pnt2d(VV,UU);
701 else
702 return gp_Pnt2d(UU,VV);
703}
704
705//=======================================================================
706//function : ValueOnF1
707//purpose :
708//=======================================================================
709
710gp_Pnt2d BRepFill_MultiLine::ValueOnF1(const Standard_Real U) const
711{
712 return ValueOnFace(U,myBis,myU1,myV1,myIsoU1);
713}
714
715
716//=======================================================================
717//function : ValueOnF2
718//purpose :
719//=======================================================================
720
721gp_Pnt2d BRepFill_MultiLine::ValueOnF2(const Standard_Real U) const
722{
723 return ValueOnFace(U,myBis,myU2,myV2,myIsoU2);
724}
725
726//=======================================================================
727//function : Value3dOnF1OnF2
728//purpose :
729//=======================================================================
730
731void BRepFill_MultiLine::Value3dOnF1OnF2(const Standard_Real U,
df573a26 732 gp_Pnt& P3d,
733 gp_Pnt2d& PF1,
734 gp_Pnt2d& PF2)
735 const
7fd59977 736{
737 PF1 = ValueOnFace(U,myBis,myU1,myV1,myIsoU1);
738 PF2 = ValueOnFace(U,myBis,myU2,myV2,myIsoU2);
739
740 Handle(Geom_Surface) S;
741 TopLoc_Location L;
742
743 S = BRep_Tool::Surface(myFace1,L);
744 P3d = S->Value(PF1.X(), PF1.Y());
745 P3d.Transform(L.Transformation());
746}
747
748//=======================================================================
749//function : Continuity
750//purpose :
751//=======================================================================
752
753GeomAbs_Shape BRepFill_MultiLine::Continuity() const
754{
755 return myCont;
756}
368cdde6 757
758//=======================================================================
759//function : Value
760//purpose :
761//=======================================================================
762
763Standard_Boolean BRepFill_MultiLine::Value(const Standard_Real theT,
df573a26 764 NCollection_Array1<gp_Pnt2d>& thePnt2d,
765 NCollection_Array1<gp_Pnt>& thePnt) const
766{
767 thePnt(1) = Value(theT);
768 thePnt2d(1) = ValueOnF1(theT);
769 thePnt2d(2) = ValueOnF2(theT);
770 return Standard_True;
771}
368cdde6 772
773//=======================================================================
774//function : Value
775//purpose :
776//=======================================================================
777
778Standard_Boolean BRepFill_MultiLine::D1(const Standard_Real /*theT*/,
df573a26 779 NCollection_Array1<gp_Vec2d>& /*theVec2d*/,
780 NCollection_Array1<gp_Vec>& /*theVec*/) const
368cdde6 781{
782 return Standard_False;
783}