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