Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1995-04-24 |
2 | // Created by: Bruno DUMORTIER | |
3 | // Copyright (c) 1995-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 | |
42cf5bc1 | 17 | |
18 | #include <Bisector_Bisec.hxx> | |
7fd59977 | 19 | #include <Bisector_BisecAna.hxx> |
42cf5bc1 | 20 | #include <BRep_Tool.hxx> |
21 | #include <BRepFill_TrimEdgeTool.hxx> | |
22 | #include <ElCLib.hxx> | |
23 | #include <Geom2d_CartesianPoint.hxx> | |
7fd59977 | 24 | #include <Geom2d_Curve.hxx> |
42cf5bc1 | 25 | #include <Geom2d_Geometry.hxx> |
7fd59977 | 26 | #include <Geom2d_TrimmedCurve.hxx> |
7fd59977 | 27 | #include <Geom2dAPI_ProjectPointOnCurve.hxx> |
28 | #include <Geom2dInt_GInter.hxx> | |
42cf5bc1 | 29 | #include <Geom_Curve.hxx> |
30 | #include <Geom_TrimmedCurve.hxx> | |
31 | #include <GeomProjLib.hxx> | |
7fd59977 | 32 | #include <gp_Pnt.hxx> |
42cf5bc1 | 33 | #include <gp_Pnt2d.hxx> |
7fd59977 | 34 | #include <IntRes2d_IntersectionPoint.hxx> |
35 | #include <IntRes2d_IntersectionSegment.hxx> | |
42cf5bc1 | 36 | #include <Precision.hxx> |
7fd59977 | 37 | #include <StdFail_NotDone.hxx> |
42cf5bc1 | 38 | #include <TopLoc_Location.hxx> |
39 | #include <TopoDS.hxx> | |
40 | #include <TopoDS_Edge.hxx> | |
46767247 | 41 | #include <TopoDS_Vertex.hxx> |
42 | #include <TopExp.hxx> | |
43 | #include <BRepAdaptor_Curve.hxx> | |
42cf5bc1 | 44 | |
873c119f | 45 | #ifdef OCCT_DEBUG |
46 | //#define DRAW | |
7fd59977 | 47 | #ifdef DRAW |
48 | #include <DrawTrSurf.hxx> | |
49 | #include <DBRep.hxx> | |
ec357c5c | 50 | #include <Geom2d_Point.hxx> |
7fd59977 | 51 | static Standard_Boolean Affich = Standard_False; |
873c119f | 52 | static Standard_Boolean AffichInt = Standard_False; |
53 | static Standard_Integer intind = 0; | |
54 | #endif | |
7fd59977 | 55 | #endif |
56 | ||
57 | ||
58 | //======================================================================= | |
59 | //function : SimpleExpression | |
60 | //purpose : | |
61 | //======================================================================= | |
62 | ||
63 | static void SimpleExpression (const Bisector_Bisec& B, | |
873c119f | 64 | Handle(Geom2d_Curve)& Bis) |
7fd59977 | 65 | { |
66 | Bis = B.Value(); | |
67 | ||
68 | Handle(Standard_Type) BT = Bis->DynamicType(); | |
69 | if (BT == STANDARD_TYPE(Geom2d_TrimmedCurve)) { | |
70 | Handle(Geom2d_TrimmedCurve) TrBis | |
71 | = Handle(Geom2d_TrimmedCurve)::DownCast(Bis); | |
72 | Handle(Geom2d_Curve) BasBis = TrBis->BasisCurve(); | |
73 | BT = BasBis->DynamicType(); | |
74 | if (BT == STANDARD_TYPE(Bisector_BisecAna)) { | |
75 | Bis = Handle(Bisector_BisecAna)::DownCast(BasBis)->Geom2dCurve(); | |
76 | Bis = new Geom2d_TrimmedCurve (Bis, | |
873c119f | 77 | TrBis->FirstParameter(), |
78 | TrBis->LastParameter()); | |
7fd59977 | 79 | } |
80 | } | |
81 | } | |
82 | ||
83 | ||
84 | //======================================================================= | |
85 | //function : BRepFill_TrimEdgeTool | |
86 | //purpose : | |
87 | //======================================================================= | |
88 | ||
89 | BRepFill_TrimEdgeTool::BRepFill_TrimEdgeTool() | |
90 | { | |
91 | } | |
92 | ||
93 | ||
94 | //======================================================================= | |
95 | //function : BRepFill_TrimEdgeTool | |
96 | //purpose : | |
97 | //======================================================================= | |
98 | ||
99 | BRepFill_TrimEdgeTool::BRepFill_TrimEdgeTool | |
873c119f | 100 | (const Bisector_Bisec& Bisec, |
101 | const Handle(Geom2d_Geometry)& S1, | |
102 | const Handle(Geom2d_Geometry)& S2, | |
103 | const Standard_Real Offset) : | |
7fd59977 | 104 | myOffset(Offset), |
873c119f | 105 | myBisec(Bisec) |
7fd59977 | 106 | { |
107 | isPoint1 = (S1->DynamicType() == STANDARD_TYPE(Geom2d_CartesianPoint)); | |
108 | isPoint2 = (S2->DynamicType() == STANDARD_TYPE(Geom2d_CartesianPoint)); | |
109 | ||
873c119f | 110 | // return geometries of shapes. |
111 | // Standard_Real f,l; | |
7fd59977 | 112 | if (isPoint1) { |
113 | myP1 = Handle(Geom2d_Point)::DownCast(S1)->Pnt2d(); | |
114 | } | |
115 | else { | |
116 | myC1 = Handle(Geom2d_Curve)::DownCast(S1); | |
117 | #ifdef DRAW | |
118 | if ( Affich) { | |
873c119f | 119 | //POP pour NT |
7fd59977 | 120 | char* myC1name = "myC1"; |
121 | DrawTrSurf::Set(myC1name,myC1); | |
873c119f | 122 | // DrawTrSurf::Set("myC1",myC1); |
7fd59977 | 123 | } |
124 | #endif | |
125 | } | |
126 | if (isPoint2) { | |
127 | myP2 = Handle(Geom2d_Point)::DownCast(S2)->Pnt2d(); | |
128 | } | |
129 | else { | |
130 | myC2 = Handle(Geom2d_Curve)::DownCast(S2); | |
131 | #ifdef DRAW | |
132 | if ( Affich) { | |
133 | char* myC2name = "myC2"; | |
134 | DrawTrSurf::Set(myC2name,myC2); | |
873c119f | 135 | // DrawTrSurf::Set("myC2",myC2); |
7fd59977 | 136 | } |
137 | #endif | |
138 | } | |
0d969553 | 139 | // return the simple expression of the bissectrice |
7fd59977 | 140 | Handle(Geom2d_Curve) Bis; |
141 | SimpleExpression(myBisec, Bis); | |
142 | myBis = Geom2dAdaptor_Curve(Bis); | |
143 | #ifdef DRAW | |
144 | if ( Affich) { | |
873c119f | 145 | char* myBisname = "myBis"; |
146 | DrawTrSurf::Set(myBisname,Bis); | |
7fd59977 | 147 | } |
148 | #endif | |
149 | ||
150 | } | |
151 | ||
152 | //======================================================================= | |
153 | //function : Bubble | |
0d969553 | 154 | //purpose : Order the sequence of points by increasing x. |
7fd59977 | 155 | //======================================================================= |
156 | ||
157 | static void Bubble(TColgp_SequenceOfPnt& Seq) | |
158 | { | |
159 | Standard_Boolean Invert = Standard_True; | |
160 | Standard_Integer NbPoints = Seq.Length(); | |
161 | while (Invert) { | |
162 | Invert = Standard_False; | |
163 | for ( Standard_Integer i = 1; i < NbPoints; i++) { | |
164 | gp_Pnt P1 = Seq.Value(i); | |
165 | gp_Pnt P2 = Seq.Value(i+1); | |
166 | if (P2.X()<P1.X()) { | |
873c119f | 167 | Seq.Exchange(i,i+1); |
168 | Invert = Standard_True; | |
7fd59977 | 169 | } |
170 | } | |
171 | } | |
172 | } | |
173 | ||
174 | ||
175 | //======================================================================= | |
0d969553 | 176 | //function : EvalParameters |
7fd59977 | 177 | //purpose : |
178 | //======================================================================= | |
179 | ||
180 | static void EvalParameters(const Geom2dAdaptor_Curve& Bis, | |
873c119f | 181 | const Geom2dAdaptor_Curve& AC, |
182 | TColgp_SequenceOfPnt& Params) | |
7fd59977 | 183 | { |
184 | Geom2dInt_GInter Intersector; | |
5768cd55 | 185 | Standard_Real Tol = Precision::Confusion(); |
873c119f | 186 | // Standard_Real TolC = 1.e-9; |
7fd59977 | 187 | |
188 | Geom2dAdaptor_Curve CBis(Bis); | |
189 | Geom2dAdaptor_Curve CAC (AC); | |
190 | ||
7fd59977 | 191 | //Intersector = Geom2dInt_GInter(CBis, CAC, TolC, Tol); |
192 | Intersector = Geom2dInt_GInter(CAC, CBis, Tol, Tol); | |
193 | ||
194 | Standard_Integer NbPoints, NbSegments; | |
195 | Standard_Real U1, U2; | |
196 | gp_Pnt P; | |
197 | ||
198 | if ( !Intersector.IsDone()) { | |
9775fa61 | 199 | throw StdFail_NotDone("BRepFill_TrimSurfaceTool::IntersectWith"); |
7fd59977 | 200 | } |
873c119f | 201 | |
7fd59977 | 202 | NbPoints = Intersector.NbPoints(); |
873c119f | 203 | |
7fd59977 | 204 | if (NbPoints > 0) { |
205 | for ( Standard_Integer i = 1; i <= NbPoints; i++) { | |
206 | U1 = Intersector.Point(i).ParamOnSecond(); | |
207 | U2 = Intersector.Point(i).ParamOnFirst(); | |
208 | P = gp_Pnt(U1,U2,0.); | |
209 | Params.Append(P); | |
210 | } | |
873c119f | 211 | |
7fd59977 | 212 | } |
873c119f | 213 | |
7fd59977 | 214 | NbSegments = Intersector.NbSegments(); |
873c119f | 215 | |
7fd59977 | 216 | if (NbSegments > 0) { |
217 | IntRes2d_IntersectionSegment Seg; | |
218 | for ( Standard_Integer i = 1; i <= NbSegments; i++) { | |
219 | Seg = Intersector.Segment(i); | |
220 | U1 = Seg.FirstPoint().ParamOnSecond(); | |
221 | Standard_Real Ulast = Seg.LastPoint().ParamOnSecond(); | |
222 | if ( Abs(U1 - CBis.FirstParameter()) <= Tol && | |
873c119f | 223 | Abs(Ulast - CBis.LastParameter()) <= Tol ) { |
224 | P = gp_Pnt(U1,Seg.FirstPoint().ParamOnFirst(),0.); | |
225 | Params.Append(P); | |
226 | P = gp_Pnt(Ulast,Seg.LastPoint().ParamOnFirst(),0.); | |
227 | Params.Append(P); | |
7fd59977 | 228 | } |
229 | else { | |
873c119f | 230 | U1 += Seg.LastPoint().ParamOnSecond(); |
231 | U1 /= 2.; | |
232 | U2 = Seg.FirstPoint().ParamOnFirst(); | |
233 | U2 += Seg.LastPoint().ParamOnFirst(); | |
234 | U2 /= 2.; | |
235 | P = gp_Pnt(U1,U2,0.); | |
236 | Params.Append(P); | |
7fd59977 | 237 | } |
238 | } | |
239 | } | |
240 | ||
0d969553 | 241 | // Order the sequence by growing parameter on the bissectrice. |
7fd59977 | 242 | Bubble( Params); |
243 | } | |
873c119f | 244 | |
7fd59977 | 245 | static void EvalParametersBis(const Geom2dAdaptor_Curve& Bis, |
873c119f | 246 | const Geom2dAdaptor_Curve& AC, |
247 | TColgp_SequenceOfPnt& Params, | |
248 | const Standard_Real Tol) | |
7fd59977 | 249 | { |
250 | Geom2dInt_GInter Intersector; | |
251 | Standard_Real TolC = Tol; | |
873c119f | 252 | |
7fd59977 | 253 | Geom2dAdaptor_Curve CBis(Bis); |
254 | Geom2dAdaptor_Curve CAC (AC); | |
255 | ||
256 | Intersector = Geom2dInt_GInter(CAC, CBis, TolC, Tol); | |
257 | ||
258 | Standard_Integer NbPoints, NbSegments; | |
259 | Standard_Real U1, U2; | |
260 | gp_Pnt P; | |
261 | ||
262 | if ( !Intersector.IsDone()) { | |
9775fa61 | 263 | throw StdFail_NotDone("BRepFill_TrimSurfaceTool::IntersectWith"); |
7fd59977 | 264 | } |
873c119f | 265 | |
7fd59977 | 266 | NbPoints = Intersector.NbPoints(); |
873c119f | 267 | |
7fd59977 | 268 | if (NbPoints > 0) { |
269 | for ( Standard_Integer i = 1; i <= NbPoints; i++) { | |
270 | U1 = Intersector.Point(i).ParamOnSecond(); | |
271 | U2 = Intersector.Point(i).ParamOnFirst(); | |
272 | P = gp_Pnt(U1,U2,0.); | |
273 | Params.Append(P); | |
274 | } | |
873c119f | 275 | |
7fd59977 | 276 | } |
873c119f | 277 | |
7fd59977 | 278 | NbSegments = Intersector.NbSegments(); |
873c119f | 279 | |
7fd59977 | 280 | if (NbSegments > 0) { |
281 | IntRes2d_IntersectionSegment Seg; | |
282 | for ( Standard_Integer i = 1; i <= NbSegments; i++) { | |
283 | Seg = Intersector.Segment(i); | |
284 | U1 = Seg.FirstPoint().ParamOnSecond(); | |
285 | Standard_Real Ulast = Seg.LastPoint().ParamOnSecond(); | |
286 | if ( Abs(U1 - CBis.FirstParameter()) <= Tol && | |
873c119f | 287 | Abs(Ulast - CBis.LastParameter()) <= Tol ) { |
288 | P = gp_Pnt(U1,Seg.FirstPoint().ParamOnFirst(),0.); | |
289 | Params.Append(P); | |
290 | P = gp_Pnt(Ulast,Seg.LastPoint().ParamOnFirst(),0.); | |
291 | Params.Append(P); | |
7fd59977 | 292 | } |
293 | else { | |
873c119f | 294 | U1 += Seg.LastPoint().ParamOnSecond(); |
295 | U1 /= 2.; | |
296 | U2 = Seg.FirstPoint().ParamOnFirst(); | |
297 | U2 += Seg.LastPoint().ParamOnFirst(); | |
298 | U2 /= 2.; | |
299 | P = gp_Pnt(U1,U2,0.); | |
300 | Params.Append(P); | |
7fd59977 | 301 | } |
302 | } | |
303 | } | |
304 | ||
0d969553 | 305 | // Order the sequence by parameter growing on the bissectrice. |
7fd59977 | 306 | Bubble( Params); |
307 | } | |
308 | ||
309 | ||
310 | //======================================================================= | |
311 | //function : IntersectWith | |
312 | //purpose : | |
313 | //======================================================================= | |
314 | ||
315 | void BRepFill_TrimEdgeTool::IntersectWith(const TopoDS_Edge& Edge1, | |
9eb68d38 | 316 | const TopoDS_Edge& Edge2, |
46767247 | 317 | const TopoDS_Shape& InitShape1, |
318 | const TopoDS_Shape& InitShape2, | |
319 | const TopoDS_Vertex& End1, | |
320 | const TopoDS_Vertex& End2, | |
9eb68d38 | 321 | const GeomAbs_JoinType theJoinType, |
46767247 | 322 | const Standard_Boolean IsOpenResult, |
9eb68d38 | 323 | TColgp_SequenceOfPnt& Params) |
7fd59977 | 324 | { |
325 | Params.Clear(); | |
326 | ||
0d969553 | 327 | // return curves associated to edges. |
7fd59977 | 328 | TopLoc_Location L; |
329 | Standard_Real f,l; | |
330 | Handle(Geom_Surface) Surf; | |
331 | ||
332 | Handle(Geom2d_Curve) C1; | |
333 | BRep_Tool::CurveOnSurface(Edge1,C1,Surf,L,f,l); | |
334 | Geom2dAdaptor_Curve AC1(C1,f,l); | |
335 | ||
336 | Handle(Geom2d_Curve) C2; | |
337 | BRep_Tool::CurveOnSurface(Edge2,C2,Surf,L,f,l); | |
338 | Geom2dAdaptor_Curve AC2(C2,f,l); | |
339 | ||
340 | #ifdef DRAW | |
873c119f | 341 | if ( AffichInt) { |
7fd59977 | 342 | f = AC1.FirstParameter(); |
343 | l = AC1.LastParameter(); | |
873c119f | 344 | char name[32]; |
345 | sprintf(name,"C1_%d", ++intind); | |
346 | DrawTrSurf::Set(name, new Geom2d_TrimmedCurve(C1,f,l)); | |
7fd59977 | 347 | f = AC2.FirstParameter(); |
348 | l = AC2.LastParameter(); | |
873c119f | 349 | sprintf(name,"C2_%d", intind); |
350 | DrawTrSurf::Set(name, new Geom2d_TrimmedCurve(C2,f,l)); | |
7fd59977 | 351 | f = myBis.FirstParameter(); |
352 | l = myBis.LastParameter(); | |
873c119f | 353 | sprintf(name,"BIS%d", intind); |
354 | DrawTrSurf::Set(name, new Geom2d_TrimmedCurve(myBis.Curve(),f,l)); | |
355 | sprintf(name,"E1_%d", intind); | |
356 | DBRep::Set(name, Edge1); | |
357 | sprintf(name,"E2_%d", intind); | |
358 | DBRep::Set(name, Edge2); | |
7fd59977 | 359 | |
360 | } | |
361 | #endif | |
873c119f | 362 | |
0d969553 | 363 | // Calculate intersection |
7fd59977 | 364 | TColgp_SequenceOfPnt Points2; |
365 | gp_Pnt PSeq; | |
366 | ||
367 | EvalParameters (myBis,AC1,Params); | |
368 | EvalParameters (myBis,AC2,Points2); | |
369 | ||
370 | ||
873c119f | 371 | |
7fd59977 | 372 | Standard_Integer SeanceDeRattrapage=0; |
373 | Standard_Real TolInit= 1.e-9; | |
374 | Standard_Integer nn = 7; | |
375 | ||
0ebaa4db | 376 | if((AC1.GetType() != GeomAbs_Circle && AC1.GetType() != GeomAbs_Line) || |
873c119f | 377 | (AC2.GetType() != GeomAbs_Circle && AC2.GetType() != GeomAbs_Line)) { |
378 | ||
379 | TolInit = 1.e-8; | |
380 | nn = 6; | |
381 | } | |
7fd59977 | 382 | |
873c119f | 383 | if(Params.IsEmpty() && Points2.IsEmpty()) |
384 | { | |
385 | //Check, may be there are no intersections at all | |
386 | // for case myBis == Line | |
387 | if(myBis.GetType() == GeomAbs_Line) | |
388 | { | |
389 | Standard_Real dmax = TolInit; | |
390 | Standard_Integer n = 0; | |
391 | while(n < nn) | |
392 | { | |
393 | dmax *= 10.0; | |
394 | ++n; | |
395 | } | |
396 | dmax *= dmax; | |
397 | // | |
398 | gp_Lin2d anL = myBis.Line(); | |
399 | Standard_Boolean isFar1 = Standard_True; | |
400 | Standard_Boolean isFar2 = Standard_True; | |
401 | gp_Pnt2d aP; | |
402 | // | |
403 | Standard_Real d = RealLast(); | |
404 | AC1.D0(AC1.FirstParameter(), aP); | |
405 | Standard_Real par = ElCLib::Parameter(anL, aP); | |
406 | if(par >= myBis.FirstParameter() && par <= myBis.LastParameter()) | |
407 | { | |
408 | d = anL.SquareDistance(aP); | |
409 | } | |
410 | AC1.D0(AC1.LastParameter(), aP); | |
411 | par = ElCLib::Parameter(anL, aP); | |
412 | if(par >= myBis.FirstParameter() && par <= myBis.LastParameter()) | |
413 | { | |
414 | d = Min(anL.SquareDistance(aP), d); | |
415 | } | |
416 | isFar1 = d > dmax; | |
417 | // | |
418 | d = RealLast(); | |
419 | AC2.D0(AC2.FirstParameter(), aP); | |
420 | par = ElCLib::Parameter(anL, aP); | |
421 | if(par >= myBis.FirstParameter() && par <= myBis.LastParameter()) | |
422 | { | |
423 | d = anL.SquareDistance(aP); | |
424 | } | |
425 | AC2.D0(AC2.LastParameter(), aP); | |
426 | par = ElCLib::Parameter(anL, aP); | |
427 | if(par >= myBis.FirstParameter() && par <= myBis.LastParameter()) | |
428 | { | |
429 | d = Min(anL.SquareDistance(aP), d); | |
430 | } | |
431 | isFar2 = d > dmax; | |
432 | // | |
433 | if(isFar1 && isFar2) | |
434 | { | |
435 | return; | |
436 | } | |
437 | } | |
7fd59977 | 438 | } |
873c119f | 439 | |
7fd59977 | 440 | while ( SeanceDeRattrapage < nn // TolInit <= 0.01 |
873c119f | 441 | && ( Points2.Length() != Params.Length() || |
442 | (Points2.Length() == 0 && Params.Length() == 0) ) ) { | |
7fd59977 | 443 | |
0797d9d3 | 444 | #ifdef OCCT_DEBUG |
04232180 | 445 | std::cout << "BRepFill_TrimEdgeTool: incoherent intersection. Try with a greater tolerance" << std::endl; |
7fd59977 | 446 | #endif |
447 | ||
873c119f | 448 | Params.Clear(); |
449 | Points2.Clear(); | |
450 | ||
451 | TolInit*=10.0; | |
452 | ||
453 | EvalParametersBis(myBis,AC1,Params,TolInit); | |
454 | EvalParametersBis(myBis,AC2,Points2,TolInit); | |
455 | SeanceDeRattrapage++; | |
7fd59977 | 456 | } |
457 | ||
0797d9d3 | 458 | #ifdef OCCT_DEBUG |
04232180 | 459 | if(SeanceDeRattrapage != 0) std::cout << "SeanceDeRattrapage = " << SeanceDeRattrapage << std::endl; |
7fd59977 | 460 | if(SeanceDeRattrapage == nn) { |
04232180 | 461 | std::cout << "BRepFill_TrimEdgeTool: incoherent intersection" << std::endl; |
7fd59977 | 462 | } |
463 | #endif | |
464 | ||
465 | ||
466 | if(Params.Length() == 0 && Points2.Length() == 1) { | |
467 | ||
04232180 | 468 | //std::cout << "Params.Length() == 0 && Points2.Length() == 1" << std::endl; |
873c119f | 469 | Standard_Real dmin, dmax = 0.25*myOffset*myOffset; |
7fd59977 | 470 | Standard_Real tBis = Points2(1).X(); |
471 | gp_Pnt2d PBis = myBis.Value(tBis); | |
472 | ||
473 | Standard_Real t = AC1.FirstParameter(); | |
474 | gp_Pnt2d PC = AC1.Value(t); | |
475 | dmin = PC.SquareDistance(PBis); | |
476 | gp_Pnt P(tBis, t, 0.); | |
873c119f | 477 | if(dmin < dmax) |
478 | { | |
479 | Params.Append(P); | |
480 | } | |
7fd59977 | 481 | |
482 | t = AC1.LastParameter(); | |
483 | PC = AC1.Value(t); | |
873c119f | 484 | Standard_Real dmin1 = PC.SquareDistance(PBis); |
485 | if(dmin > dmin1 && dmin1 < dmax ) { | |
7fd59977 | 486 | P.SetY(t); |
873c119f | 487 | if(Params.IsEmpty()) |
488 | Params.Append(P); | |
489 | else | |
490 | Params.SetValue(1,P); | |
7fd59977 | 491 | } |
492 | } | |
493 | else if(Params.Length() == 1 && Points2.Length() == 0) { | |
494 | ||
04232180 | 495 | //std::cout << "Params.Length() == 1 && Points2.Length() == 0" << std::endl; |
873c119f | 496 | Standard_Real dmin, dmax = 0.25*myOffset*myOffset; |
7fd59977 | 497 | Standard_Real tBis = Params(1).X(); |
498 | gp_Pnt2d PBis = myBis.Value(tBis); | |
499 | ||
500 | Standard_Real t = AC2.FirstParameter(); | |
501 | gp_Pnt2d PC = AC2.Value(t); | |
502 | dmin = PC.SquareDistance(PBis); | |
503 | gp_Pnt P(tBis, t, 0.); | |
873c119f | 504 | if(dmin < dmax) |
505 | { | |
506 | Points2.Append(P); | |
507 | } | |
7fd59977 | 508 | |
509 | t = AC2.LastParameter(); | |
510 | PC = AC2.Value(t); | |
873c119f | 511 | Standard_Real dmin1 = PC.SquareDistance(PBis); |
512 | if(dmin > dmin1 && dmin1 < dmax ) { | |
7fd59977 | 513 | P.SetY(t); |
873c119f | 514 | if(Points2.IsEmpty()) |
515 | Points2.Append(P); | |
516 | else | |
517 | Points2.SetValue(1,P); | |
7fd59977 | 518 | } |
519 | } | |
520 | ||
0d969553 Y |
521 | // small manipulation to remove incorrect intersections: |
522 | // return only common intersections (same parameter | |
523 | // on the bissectrice.). | |
524 | // The tolerance can be eventually changed. | |
7fd59977 | 525 | |
526 | gp_Pnt P1,P2; | |
527 | Standard_Real Tol = 4 * 100 * Precision::PConfusion(); | |
528 | Standard_Integer i = 1; | |
529 | Standard_Integer NbPoints = Params.Length(); | |
530 | ||
531 | if(NbPoints == 1 && Points2.Length() == 1) { | |
04232180 | 532 | //std::cout << "NbPoints == 1 && Points2.Length() == 1" << std::endl; |
7fd59977 | 533 | for ( i = 1; i <= NbPoints; i++) { |
534 | PSeq = Params(i); | |
535 | PSeq.SetZ((Points2.Value(i)).Y()); | |
536 | Params.SetValue(i,PSeq); | |
537 | } | |
538 | return; | |
539 | } | |
540 | ||
541 | i = 1; | |
542 | while ( i <= Min( Params.Length(), Points2.Length())) { | |
543 | P1 = Params(i); | |
544 | P2 = Points2(i); | |
545 | Standard_Real P1xP2x=Abs( P1.X() - P2.X()); | |
546 | ||
547 | if ( P1xP2x > Tol ) { | |
0797d9d3 | 548 | #ifdef OCCT_DEBUG |
04232180 | 549 | std::cout << "BRepFill_TrimEdgeTool: no same parameter on the bissectrice" << std::endl; |
7fd59977 | 550 | #endif |
551 | if(P1xP2x>TolInit) { | |
0797d9d3 | 552 | #ifdef OCCT_DEBUG |
04232180 | 553 | std::cout << "BRepFill_TrimEdgeTool: Continue somehow" << std::endl; |
7fd59977 | 554 | #endif |
873c119f | 555 | i++; |
7fd59977 | 556 | } |
557 | else { | |
873c119f | 558 | if ( P1.X() < P2.X()) Params.Remove(i); |
559 | else Points2.Remove(i); | |
7fd59977 | 560 | } |
561 | } | |
562 | else i++; | |
563 | } | |
564 | ||
565 | if ( Params.Length() > Points2.Length()) { | |
566 | Params.Remove(Points2.Length()+1, Params.Length()); | |
567 | } | |
568 | else if ( Params.Length() < Points2.Length()) { | |
569 | Points2.Remove(Params.Length()+1, Points2.Length()); | |
570 | } | |
571 | ||
9eb68d38 | 572 | NbPoints = Params.Length(); |
573 | ||
46767247 | 574 | //Now we define: if there are more than one point of intersection |
575 | //is it Ok ? | |
576 | Standard_Real init_fpar = RealFirst(), init_lpar = RealLast(); | |
577 | if (NbPoints > 1 && | |
578 | theJoinType == GeomAbs_Intersection && | |
579 | InitShape1.ShapeType() != TopAbs_VERTEX && | |
580 | InitShape2.ShapeType() != TopAbs_VERTEX) | |
581 | { | |
582 | //definition of initial first and last parameters: | |
583 | //this is inverse procedure to extension of parameters | |
584 | //(see BRepFill_OffsetWire, function MakeOffset, case of Circle) | |
585 | const TopoDS_Edge& InitEdge1 = TopoDS::Edge(InitShape1); | |
586 | Standard_Boolean ToExtendFirstPar = Standard_True; | |
587 | Standard_Boolean ToExtendLastPar = Standard_True; | |
588 | if (IsOpenResult) | |
589 | { | |
590 | TopoDS_Vertex V1, V2; | |
591 | TopExp::Vertices(InitEdge1, V1, V2); | |
592 | if (V1.IsSame(End1) || | |
593 | V1.IsSame(End2)) | |
594 | ToExtendFirstPar = Standard_False; | |
595 | if (V2.IsSame(End1) || | |
596 | V2.IsSame(End2)) | |
597 | ToExtendLastPar = Standard_False; | |
598 | } | |
599 | BRepAdaptor_Curve IC1(InitEdge1); | |
600 | if (IC1.GetType() == GeomAbs_Circle) | |
601 | { | |
602 | Standard_Real Delta = 2*M_PI - IC1.LastParameter() + IC1.FirstParameter(); | |
603 | if (ToExtendFirstPar && ToExtendLastPar) | |
604 | init_fpar = AC1.FirstParameter() + Delta/2; | |
605 | else if (ToExtendFirstPar) | |
606 | init_fpar = AC1.FirstParameter() + Delta; | |
607 | else if (ToExtendLastPar) | |
608 | init_fpar = AC1.FirstParameter(); | |
609 | init_lpar = init_fpar + IC1.LastParameter() - IC1.FirstParameter(); | |
610 | } | |
611 | } | |
612 | ||
613 | ||
614 | if (NbPoints > 1 && theJoinType == GeomAbs_Intersection) | |
9eb68d38 | 615 | { |
616 | //Remove all vertices with non-minimal parameter | |
46767247 | 617 | //if they are out of initial range |
9eb68d38 | 618 | Standard_Integer imin = 1; |
619 | for (i = 2; i <= NbPoints; i++) | |
620 | if (Params(i).X() < Params(imin).X()) | |
621 | imin = i; | |
46767247 | 622 | |
623 | TColgp_SequenceOfPnt ParamsCopy = Params; | |
624 | TColgp_SequenceOfPnt Points2Copy = Points2; | |
625 | Params.Clear(); | |
626 | Points2.Clear(); | |
627 | for (i = 1; i <= ParamsCopy.Length(); i++) | |
628 | if (imin == i || | |
629 | (ParamsCopy(i).Y() >= init_fpar && ParamsCopy(i).Y() <= init_lpar)) | |
630 | { | |
631 | Params.Append(ParamsCopy(i)); | |
632 | Points2.Append(Points2Copy(i)); | |
633 | } | |
634 | ||
635 | /* | |
9eb68d38 | 636 | gp_Pnt Pnt1 = Params(imin); |
637 | gp_Pnt Pnt2 = Points2(imin); | |
638 | Params.Clear(); | |
639 | Points2.Clear(); | |
640 | Params.Append(Pnt1); | |
641 | Points2.Append(Pnt2); | |
46767247 | 642 | */ |
9eb68d38 | 643 | } |
644 | ||
7fd59977 | 645 | NbPoints = Params.Length(); |
646 | for ( i = 1; i <= NbPoints; i++) { | |
647 | PSeq = Params(i); | |
648 | PSeq.SetZ((Points2.Value(i)).Y()); | |
649 | Params.SetValue(i,PSeq); | |
650 | } | |
651 | } | |
652 | ||
653 | //======================================================================= | |
654 | //function : AddOrConfuse | |
0d969553 Y |
655 | //purpose : the first or the last point of the bissectrice is on the |
656 | // parallel if it was not found in the intersections, | |
657 | // it is projected on parallel lines and added in the parameters | |
7fd59977 | 658 | //======================================================================= |
659 | ||
660 | void BRepFill_TrimEdgeTool::AddOrConfuse(const Standard_Boolean Start, | |
873c119f | 661 | const TopoDS_Edge& Edge1, |
662 | const TopoDS_Edge& Edge2, | |
663 | TColgp_SequenceOfPnt& Params) | |
664 | const | |
7fd59977 | 665 | { |
666 | Standard_Boolean ToProj = Standard_True; | |
667 | gp_Pnt2d PBis; | |
668 | Standard_Real Tol = 10*Precision::Confusion(); | |
669 | ||
0d969553 | 670 | // return curves associated to edges. |
7fd59977 | 671 | TopLoc_Location L; |
672 | Standard_Real f,l; | |
673 | Handle(Geom_Surface) Surf; | |
674 | ||
675 | Handle(Geom2d_Curve) C1; | |
676 | BRep_Tool::CurveOnSurface(Edge1,C1,Surf,L,f,l); | |
677 | Geom2dAdaptor_Curve AC1(C1,f,l); | |
678 | ||
679 | ||
680 | if (Start) PBis = myBis.Value(myBis.FirstParameter()); | |
681 | else PBis = myBis.Value(myBis.LastParameter ()); | |
682 | ||
0d969553 | 683 | // Test if the end of the bissectrice is in the set of intersection points. |
7fd59977 | 684 | if (!Params.IsEmpty()) { |
685 | gp_Pnt2d P; | |
686 | if (Start) P = AC1.Value(Params.First().Y()); | |
687 | else P = AC1.Value(Params.Last ().Y()); | |
688 | ToProj = !PBis.IsEqual(P,Tol); | |
689 | } | |
873c119f | 690 | |
7fd59977 | 691 | if (ToProj) { |
0797d9d3 | 692 | #ifdef OCCT_DEBUG |
04232180 | 693 | std::cout << " project extremity bissectrice on parallel."<<std::endl; |
7fd59977 | 694 | #endif |
695 | ||
0d969553 | 696 | // Project point on parallels and add in Params |
7fd59977 | 697 | |
698 | Standard_Real f2,l2; | |
699 | Handle(Geom2d_Curve) C2; | |
700 | BRep_Tool::CurveOnSurface(Edge2,C2,Surf,L,f2,l2); | |
701 | ||
702 | Geom2dAPI_ProjectPointOnCurve Projector1(PBis,C1,f,l); | |
703 | Geom2dAPI_ProjectPointOnCurve Projector2(PBis,C2,f2,l2); | |
704 | ||
705 | if (Projector1.NbPoints() == 0) { | |
0797d9d3 | 706 | #ifdef OCCT_DEBUG |
04232180 | 707 | std::cout << "Failed projection in BRepFill_TrimEdgeTool::AddOrConfuse"<<std::endl; |
7fd59977 | 708 | #endif |
709 | return; | |
710 | } | |
711 | if (!Projector1.NearestPoint().IsEqual(PBis,Tol)) { | |
0797d9d3 | 712 | #ifdef OCCT_DEBUG |
04232180 | 713 | std::cout <<"Incorrect solution in BRepFill_TrimEdgeTool::AddOrConfuse"<<std::endl; |
7fd59977 | 714 | #endif |
715 | return; | |
716 | } | |
717 | if (Projector2.NbPoints() == 0) { | |
0797d9d3 | 718 | #ifdef OCCT_DEBUG |
04232180 | 719 | std::cout << "Failed projection in BRepFill_TrimEdgeTool::AddOrConfuse"<<std::endl; |
7fd59977 | 720 | #endif |
721 | return; | |
722 | } | |
723 | if (!Projector2.NearestPoint().IsEqual(PBis,Tol)) { | |
0797d9d3 | 724 | #ifdef OCCT_DEBUG |
04232180 | 725 | std::cout <<" Mauvaisesolution dans BRepFill_TrimEdgeTool::AddOrConfuse"<<std::endl; |
7fd59977 | 726 | #endif |
727 | return; | |
728 | } | |
729 | gp_Pnt PInt (0, | |
873c119f | 730 | Projector1.LowerDistanceParameter(), |
731 | Projector2.LowerDistanceParameter()); | |
7fd59977 | 732 | if (Start) { |
733 | PInt.SetX (myBis.FirstParameter()); | |
734 | Params.Prepend(PInt); | |
735 | } | |
736 | else { | |
737 | PInt.SetX (myBis.LastParameter()); | |
738 | Params.Append(PInt); | |
739 | } | |
740 | } | |
741 | } | |
742 | ||
743 | //======================================================================= | |
744 | //function : IsInside | |
745 | //purpose : | |
746 | //======================================================================= | |
747 | ||
748 | Standard_Boolean BRepFill_TrimEdgeTool::IsInside(const gp_Pnt2d& P) const | |
749 | { | |
873c119f | 750 | // Modified by Sergey KHROMOV - Fri Sep 27 11:43:12 2002 Begin |
751 | // Standard_Real Dist; | |
7fd59977 | 752 | Standard_Real Dist = RealLast(); |
873c119f | 753 | // Modified by Sergey KHROMOV - Fri Sep 27 11:43:12 2002 End |
7fd59977 | 754 | if (isPoint1) |
755 | Dist = P.Distance(myP1); | |
756 | else if (isPoint2) | |
757 | Dist = P.Distance(myP2); | |
758 | else { | |
759 | Geom2dAPI_ProjectPointOnCurve Projector(P,myC1); | |
760 | if (Projector.NbPoints() > 0) { | |
761 | Dist = Projector.LowerDistance(); | |
762 | } | |
873c119f | 763 | // Modified by Sergey KHROMOV - Fri Sep 27 11:43:43 2002 Begin |
764 | // else { | |
765 | // gp_Pnt2d PF = myC1->Value(myC1->FirstParameter()); | |
766 | // gp_Pnt2d PL = myC1->Value(myC1->LastParameter()); | |
767 | // Dist = Min (P.Distance(PF),P.Distance(PL)); | |
768 | // } | |
769 | ||
770 | // Check of distances between P and first and last point of the first curve | |
771 | // should be performed in any case, despite of the results of projection. | |
7fd59977 | 772 | gp_Pnt2d PF = myC1->Value(myC1->FirstParameter()); |
773 | gp_Pnt2d PL = myC1->Value(myC1->LastParameter()); | |
774 | Standard_Real aDistMin = Min (P.Distance(PF),P.Distance(PL)); | |
775 | ||
776 | if (Dist > aDistMin) | |
777 | Dist = aDistMin; | |
873c119f | 778 | // Modified by Sergey KHROMOV - Fri Sep 27 11:43:44 2002 End |
7fd59977 | 779 | } |
873c119f | 780 | |
781 | // return (Dist < Abs(myOffset); | |
782 | // return (Dist < Abs(myOffset) + Precision::Confusion()); | |
7fd59977 | 783 | return (Dist < Abs(myOffset) - Precision::Confusion()); |
784 | } | |
785 |