b311480e |
1 | // Created on: 1993-07-12 |
2 | // Created by: Yves FRICAUD |
3 | // Copyright (c) 1993-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 | #define Debug(expr) cout<<" MAT2d_Tool2d.cxx : expr :"<<expr<<endl; |
18 | |
19 | #ifdef DRAW |
20 | #include <DBRep.hxx> |
21 | #include <DrawTrSurf.hxx> |
22 | #include <stdio.h> |
23 | #endif |
24 | |
25 | #ifdef DRAW |
26 | #include <Draw_Appli.hxx> |
27 | #include <DrawTrSurf_Curve2d.hxx> |
28 | #include <GCE2d_MakeSegment.hxx> |
29 | #include <DrawTrSurf.hxx> |
30 | #endif |
31 | |
32 | #include <MAT2d_Tool2d.ixx> |
33 | #include <MAT2d_MiniPath.hxx> |
34 | #include <MAT2d_Connexion.hxx> |
35 | #include <MAT2d_SequenceOfSequenceOfGeometry.hxx> |
36 | #include <MAT_Edge.hxx> |
37 | #include <Bisector_Curve.hxx> |
38 | #include <Bisector_BisecAna.hxx> |
39 | #include <Bisector_BisecCC.hxx> |
40 | #include <Bisector_Bisec.hxx> |
41 | #include <Bisector_Inter.hxx> |
42 | #include <IntRes2d_Domain.hxx> |
43 | #include <Extrema_ExtPC2d.hxx> |
44 | #include <Geom2dInt_GInter.hxx> |
45 | #include <IntRes2d_IntersectionPoint.hxx> |
46 | #include <IntRes2d_IntersectionSegment.hxx> |
47 | #include <Geom2d_Geometry.hxx> |
48 | #include <Geom2d_Point.hxx> |
49 | #include <Geom2d_Line.hxx> |
50 | #include <Geom2d_Circle.hxx> |
51 | #include <Geom2d_Curve.hxx> |
52 | #include <Geom2d_Parabola.hxx> |
53 | #include <Geom2d_Hyperbola.hxx> |
54 | #include <Geom2d_Ellipse.hxx> |
55 | #include <Geom2d_CartesianPoint.hxx> |
56 | #include <Geom2d_TrimmedCurve.hxx> |
57 | #include <Geom2dAdaptor_Curve.hxx> |
58 | #include <gp_Lin2d.hxx> |
59 | #include <gp_Hypr2d.hxx> |
60 | #include <gp_Parab2d.hxx> |
61 | #include <gp_Elips2d.hxx> |
62 | #include <gp_Circ2d.hxx> |
63 | #include <gp_Vec2d.hxx> |
64 | #include <TColStd_Array1OfReal.hxx> |
65 | #include <ElCLib.hxx> |
66 | #include <StdFail_NotDone.hxx> |
67 | #include <Standard_NotImplemented.hxx> |
68 | #include <Precision.hxx> |
69 | |
70 | #ifdef DRAW |
71 | static Handle(DrawTrSurf_Curve2d) draw; |
72 | #endif |
73 | #ifdef DEB |
74 | static void MAT2d_DrawCurve(const Handle(Geom2d_Curve)& aCurve, |
75 | const Standard_Integer Indice); |
76 | static Standard_Boolean Store = Standard_False; |
77 | #endif |
78 | |
79 | //===================================================================== |
80 | // static functions |
81 | //===================================================================== |
82 | static IntRes2d_Domain Domain |
83 | (const Handle(Geom2d_TrimmedCurve)& Bisector1, |
84 | const Standard_Real Tolerance); |
85 | |
86 | static Handle(Standard_Type) Type (const Handle(Geom2d_Geometry)& acurve); |
87 | |
88 | static Standard_Boolean AreNeighbours(const Standard_Integer IEdge1, |
89 | const Standard_Integer IEdge2, |
90 | const Standard_Integer NbEdge); |
91 | |
92 | static void SetTrim(Bisector_Bisec& Bis , Handle(Geom2d_Curve)& Line1); |
93 | |
94 | static Standard_Real MAT2d_TOLCONF = 1.e-7; |
95 | |
96 | //============================================================================ |
97 | //function : |
98 | //purpose : |
99 | //============================================================================ |
100 | MAT2d_Tool2d::MAT2d_Tool2d() |
101 | { |
102 | theDirection = 1.; |
103 | theNumberOfBisectors = 0; |
104 | theNumberOfVecs = 0; |
105 | theNumberOfPnts = 0; |
106 | } |
107 | |
108 | //============================================================================= |
109 | //function : InitItems |
110 | //purpose : |
111 | //============================================================================= |
112 | void MAT2d_Tool2d::InitItems(const Handle(MAT2d_Circuit)& EquiCircuit) |
113 | { |
114 | theGeomBisectors.Clear(); |
115 | theGeomPnts.Clear(); |
116 | theGeomVecs.Clear(); |
117 | theLinesLength.Clear(); |
118 | theNumberOfBisectors = 0; |
119 | theNumberOfVecs = 0; |
120 | theNumberOfPnts = 0; |
121 | |
122 | theCircuit = EquiCircuit; |
123 | } |
124 | |
125 | //============================================================================= |
126 | //function : Sense |
127 | //purpose : |
128 | //============================================================================= |
129 | void MAT2d_Tool2d::Sense(const MAT_Side aside) |
130 | { |
131 | if(aside == MAT_Left) theDirection = 1.; |
132 | else theDirection = -1.; |
133 | } |
134 | |
135 | //============================================================================= |
136 | //function : NumberOfItems |
137 | //purpose : |
138 | //============================================================================= |
139 | Standard_Integer MAT2d_Tool2d::NumberOfItems() const |
140 | { |
141 | return theCircuit->NumberOfItems(); |
142 | } |
143 | |
144 | //============================================================================= |
145 | //function : ToleranceOfConfusion |
146 | //purpose : |
147 | //============================================================================= |
148 | Standard_Real MAT2d_Tool2d::ToleranceOfConfusion() const |
149 | { |
150 | return 2*MAT2d_TOLCONF; |
151 | } |
152 | |
153 | //============================================================================= |
154 | //function : FirstPoint |
155 | //purpose : |
156 | //============================================================================= |
157 | Standard_Integer MAT2d_Tool2d::FirstPoint(const Standard_Integer anitem, |
158 | Standard_Real& dist ) |
159 | { |
160 | Handle(Geom2d_Curve) curve; |
161 | Handle(Geom2d_Point) point; |
162 | theNumberOfPnts++; |
163 | |
164 | if (theCircuit->ConnexionOn(anitem)){ |
165 | gp_Pnt2d P1 = theCircuit->Connexion(anitem)->PointOnFirst(); |
166 | gp_Pnt2d P2 = theCircuit->Connexion(anitem)->PointOnSecond(); |
167 | theGeomPnts.Bind(theNumberOfPnts,gp_Pnt2d((P1.X() + P2.X())*0.5, |
168 | (P1.Y() + P2.Y())*0.5)); |
169 | dist = P1.Distance(P2)*0.5; |
170 | return theNumberOfPnts; |
171 | } |
172 | |
173 | Handle(Standard_Type) type; |
174 | type = theCircuit->Value(anitem)->DynamicType(); |
175 | dist = 0.; |
176 | |
177 | if ( type != STANDARD_TYPE(Geom2d_CartesianPoint)){ |
178 | curve = Handle(Geom2d_Curve)::DownCast(theCircuit->Value(anitem)); |
179 | theGeomPnts.Bind(theNumberOfPnts,curve->Value(curve->FirstParameter())); |
180 | } |
181 | else{ |
182 | point = Handle(Geom2d_Point)::DownCast(theCircuit->Value(anitem)); |
183 | theGeomPnts.Bind(theNumberOfPnts,point->Pnt2d()); |
184 | } |
185 | return theNumberOfPnts; |
186 | } |
187 | |
188 | //============================================================================= |
189 | //function : TangentBefore |
190 | //purpose : |
191 | //============================================================================= |
192 | Standard_Integer MAT2d_Tool2d::TangentBefore(const Standard_Integer anitem) |
193 | { |
194 | Standard_Integer item; |
195 | Handle(Geom2d_Curve) curve; |
196 | theNumberOfVecs++; |
197 | |
198 | item = (anitem == theCircuit->NumberOfItems()) ? 1 : (anitem + 1); |
199 | if (theCircuit->ConnexionOn(item)){ |
200 | Standard_Real x1,y1,x2,y2; |
201 | theCircuit->Connexion(item)->PointOnFirst().Coord(x1,y1); |
202 | theCircuit->Connexion(item)->PointOnSecond().Coord(x2,y2); |
203 | theGeomVecs.Bind(theNumberOfVecs,gp_Vec2d((x2-x1),(y2-y1))); |
204 | return theNumberOfVecs; |
205 | } |
206 | |
207 | Handle(Standard_Type) type; |
208 | type = theCircuit->Value(anitem)->DynamicType(); |
209 | if ( type != STANDARD_TYPE(Geom2d_CartesianPoint)){ |
210 | curve = Handle(Geom2d_Curve)::DownCast(theCircuit->Value(anitem)); |
211 | theGeomVecs.Bind(theNumberOfVecs,curve->DN(curve->LastParameter(),1)); |
212 | } |
213 | else { |
214 | curve = Handle(Geom2d_Curve)::DownCast(theCircuit->Value(item)); |
215 | theGeomVecs.Bind(theNumberOfVecs,curve->DN(curve->FirstParameter(),1)); |
216 | } |
217 | |
218 | return theNumberOfVecs; |
219 | } |
220 | |
221 | //============================================================================= |
222 | //function : TangentAfter |
223 | //purpose : |
224 | //============================================================================= |
225 | Standard_Integer MAT2d_Tool2d::TangentAfter(const Standard_Integer anitem) |
226 | { |
227 | Standard_Integer item; |
228 | Handle(Geom2d_Curve) curve; |
229 | gp_Vec2d thevector; |
230 | theNumberOfVecs++; |
231 | |
232 | if (theCircuit->ConnexionOn(anitem)){ |
233 | Standard_Real x1,y1,x2,y2; |
234 | theCircuit->Connexion(anitem)->PointOnFirst().Coord(x1,y1); |
235 | theCircuit->Connexion(anitem)->PointOnSecond().Coord(x2,y2); |
236 | theGeomVecs.Bind(theNumberOfVecs,gp_Vec2d((x1-x2),(y1-y2))); |
237 | return theNumberOfVecs; |
238 | } |
239 | |
240 | Handle(Standard_Type) type; |
241 | type = theCircuit->Value(anitem)->DynamicType(); |
242 | if ( type != STANDARD_TYPE(Geom2d_CartesianPoint)){ |
243 | curve = Handle(Geom2d_Curve)::DownCast(theCircuit->Value(anitem)); |
244 | thevector = curve->DN(curve->FirstParameter(),1); |
245 | } |
246 | else { |
247 | item = (anitem == 1) ? theCircuit->NumberOfItems() : (anitem - 1); |
248 | curve = Handle(Geom2d_Curve)::DownCast(theCircuit->Value(item)); |
249 | thevector = curve->DN(curve->LastParameter(),1); |
250 | } |
251 | theGeomVecs.Bind(theNumberOfVecs,thevector.Reversed()); |
252 | return theNumberOfVecs; |
253 | } |
254 | |
255 | //============================================================================= |
256 | //function : Tangent |
257 | //purpose : |
258 | //============================================================================= |
259 | Standard_Integer MAT2d_Tool2d::Tangent(const Standard_Integer bisector) |
260 | { |
261 | theNumberOfVecs++; |
262 | theGeomVecs.Bind(theNumberOfVecs,GeomBis(bisector).Value() |
263 | ->DN(GeomBis(bisector).Value() |
264 | ->LastParameter(),1)); |
265 | return theNumberOfVecs; |
266 | } |
267 | |
268 | //============================================================================= |
269 | //function : CreateBisector |
270 | //purpose : |
271 | //============================================================================= |
272 | void MAT2d_Tool2d::CreateBisector(const Handle(MAT_Bisector)& abisector) |
273 | { |
274 | Handle(Geom2d_Point) point1,point2; |
275 | Handle(Geom2d_Geometry) elt1,elt2; |
276 | Bisector_Bisec bisector; |
277 | Standard_Real tolerance = MAT2d_TOLCONF ; |
278 | |
279 | Standard_Integer edge1number = abisector->FirstEdge()->EdgeNumber(); |
280 | Standard_Integer edge2number = abisector->SecondEdge()->EdgeNumber(); |
281 | Standard_Boolean ontheline = AreNeighbours(edge1number, |
282 | edge2number, |
283 | NumberOfItems()); |
284 | Standard_Boolean InitialNeighbour = ontheline; |
285 | |
286 | if(theCircuit->ConnexionOn(edge2number)) ontheline = Standard_False; |
287 | |
288 | elt1 = theCircuit->Value(edge1number); |
289 | elt2 = theCircuit->Value(edge2number); |
290 | |
291 | Handle(Standard_Type) type1; |
292 | type1 = theCircuit->Value(edge1number)->DynamicType(); |
293 | Handle(Standard_Type) type2; |
294 | type2 = theCircuit->Value(edge2number)->DynamicType(); |
295 | Handle(Geom2d_Curve) item1; |
296 | Handle(Geom2d_Curve) item2; |
297 | |
298 | if ( type1 != STANDARD_TYPE(Geom2d_CartesianPoint)){ |
299 | item1 = Handle(Geom2d_Curve)::DownCast(elt1); |
300 | } |
301 | |
302 | if ( type2 != STANDARD_TYPE(Geom2d_CartesianPoint)){ |
303 | item2 = Handle(Geom2d_Curve)::DownCast(elt2); |
304 | } |
305 | |
306 | #ifdef DEB |
307 | Standard_Boolean Affich = Standard_False; |
308 | if (Affich) { |
309 | cout<<endl; |
310 | cout<<"BISECTOR number : "<<theNumberOfBisectors+1<<endl; |
311 | cout<<" Item 1 : "<<endl; |
312 | cout<<edge1number<<endl; |
313 | cout<<endl; |
314 | // elt1->Dump(1,1); |
315 | cout<<endl; |
316 | cout<<" Item 2 : "<<endl; |
317 | cout<<edge2number<<endl; |
318 | cout<<endl; |
319 | // elt2->Dump(1,1); |
320 | cout<<endl; |
321 | } |
322 | #endif |
323 | |
324 | if(type1 != STANDARD_TYPE(Geom2d_CartesianPoint) && |
325 | type2 != STANDARD_TYPE(Geom2d_CartesianPoint)) { |
326 | bisector.Perform(item1,item2, |
327 | GeomPnt (abisector->IssuePoint()), |
328 | GeomVec (abisector->FirstVector()), |
329 | GeomVec (abisector->SecondVector()), |
330 | theDirection,tolerance,ontheline); |
331 | } |
332 | else if(type1 == STANDARD_TYPE(Geom2d_CartesianPoint) && |
333 | type2 == STANDARD_TYPE(Geom2d_CartesianPoint)) { |
334 | point1 = Handle(Geom2d_Point)::DownCast(elt1); |
335 | point2 = Handle(Geom2d_Point)::DownCast(elt2); |
336 | bisector.Perform(point1,point2, |
337 | GeomPnt (abisector->IssuePoint()), |
338 | GeomVec (abisector->FirstVector()), |
339 | GeomVec (abisector->SecondVector()), |
340 | theDirection,tolerance,ontheline); |
341 | } |
342 | else if(type1 == STANDARD_TYPE(Geom2d_CartesianPoint)) { |
343 | point1 = Handle(Geom2d_Point)::DownCast(elt1); |
344 | bisector.Perform(point1,item2, |
345 | GeomPnt (abisector->IssuePoint()), |
346 | GeomVec (abisector->FirstVector()), |
347 | GeomVec (abisector->SecondVector()), |
348 | theDirection,tolerance,ontheline); |
349 | } |
350 | else { |
351 | point2 = Handle(Geom2d_Point)::DownCast(elt2); |
352 | bisector.Perform(item1,point2, |
353 | GeomPnt (abisector->IssuePoint()), |
354 | GeomVec (abisector->FirstVector()), |
355 | GeomVec (abisector->SecondVector()), |
356 | theDirection,tolerance,ontheline); |
357 | } |
358 | |
359 | //------------------------------ |
360 | // Restriction de la bisectrice. |
361 | //----------------------------- |
362 | TrimBisec(bisector,edge1number,InitialNeighbour,1); |
363 | TrimBisec(bisector,edge2number,InitialNeighbour,2); |
364 | |
365 | theNumberOfBisectors++; |
366 | theGeomBisectors.Bind(theNumberOfBisectors,bisector); |
367 | |
368 | abisector->BisectorNumber(theNumberOfBisectors); |
369 | abisector->Sense(1); |
370 | |
371 | #ifdef DEB |
372 | Standard_Boolean AffichDraw = Standard_False; |
373 | if (AffichDraw) Dump(abisector->BisectorNumber(),1); |
374 | if (Store) { |
375 | Handle(Standard_Type) Type1 = Type(bisector.Value()->BasisCurve()); |
376 | Handle(Geom2d_Curve) BasisCurve; |
377 | if (Type1 == STANDARD_TYPE(Bisector_BisecAna)) { |
378 | BasisCurve = Handle(Bisector_BisecAna) |
379 | ::DownCast(bisector.Value()->BasisCurve())->Geom2dCurve(); |
380 | #ifdef DRAW |
381 | char *name = new char[100]; |
382 | sprintf(name,"BISSEC_%d",abisector->BisectorNumber()); |
383 | DrawTrSurf::Set(name,BasisCurve); |
384 | delete [] name; |
385 | #endif |
386 | } |
387 | } |
388 | #endif |
389 | } |
390 | |
391 | //============================================================================= |
392 | //function : TrimBisec |
393 | //purpose : Restriction de la bisectrice. |
394 | // Restriction des bissectrice separant deux elements lies par une |
395 | // connexion ou l un au moins des elements est un cercle. |
396 | // Cette restriction est necessaire a la logique de l algorithme. |
397 | //============================================================================= |
398 | void MAT2d_Tool2d::TrimBisec ( Bisector_Bisec& B1, |
399 | const Standard_Integer IndexEdge, |
400 | const Standard_Boolean InitialNeighbour, |
401 | const Standard_Integer StartOrEnd ) const |
402 | { |
403 | Handle(Geom2d_Curve) Curve; |
404 | Handle(Geom2d_TrimmedCurve) LineSupportDomain,Line; |
405 | Handle(Geom2d_Line) Line1,Line2; |
406 | |
407 | //gp_Vec2d Tan1,Tan2; |
408 | gp_Pnt2d Ori; //PEdge; |
96a95605 |
409 | Standard_Integer INext; |
7fd59977 |
410 | INext = (IndexEdge == theCircuit->NumberOfItems()) ? 1 : (IndexEdge + 1); |
411 | |
412 | Handle(Standard_Type) EdgeType = theCircuit->Value(IndexEdge)->DynamicType(); |
413 | |
414 | if (EdgeType != STANDARD_TYPE(Geom2d_CartesianPoint)) { |
415 | if(!InitialNeighbour) { |
416 | Curve = Handle(Geom2d_TrimmedCurve) |
417 | ::DownCast(theCircuit->Value(IndexEdge))->BasisCurve(); |
418 | EdgeType = Curve->DynamicType(); |
419 | //------------------------------------------------------------------- |
420 | // si l edge est liee a sa voisine precedente par une connexion. |
421 | //------------------------------------------------------------------- |
422 | if (theCircuit->ConnexionOn(IndexEdge) && StartOrEnd == 1){ |
423 | if (EdgeType == STANDARD_TYPE(Geom2d_Circle)) { |
424 | Ori = Handle(Geom2d_Circle)::DownCast(Curve)->Location(); |
425 | gp_Pnt2d P2 = theCircuit->Connexion(IndexEdge)->PointOnFirst(); |
426 | Line1 = new Geom2d_Line (Ori,gp_Dir2d(P2.X() - Ori.X(), |
427 | P2.Y() - Ori.Y())); |
428 | } |
429 | } |
430 | //----------------------------------------------------------------------- |
431 | // Si l edge est liee a sa voisine suivante par une connexion. |
432 | //----------------------------------------------------------------------- |
433 | if (theCircuit->ConnexionOn(INext) && StartOrEnd == 2){ |
434 | if (EdgeType == STANDARD_TYPE(Geom2d_Circle)) { |
435 | Ori = Handle(Geom2d_Circle)::DownCast(Curve)->Location(); |
436 | gp_Pnt2d P2 = theCircuit->Connexion(INext)->PointOnSecond(); |
437 | Line2 = new Geom2d_Line (Ori,gp_Dir2d(P2.X() - Ori.X(), |
438 | P2.Y() - Ori.Y())); |
439 | } |
440 | } |
441 | if (Line1.IsNull() && Line2.IsNull()) return; |
442 | |
443 | //----------------------------------------------------------------------- |
444 | // Restriction de la bisectrice par les demi-droites liees aux connexions |
445 | // si elles existent. |
446 | //----------------------------------------------------------------------- |
447 | if (!Line1.IsNull()) { |
448 | Line = new Geom2d_TrimmedCurve(Line1,0.,Precision::Infinite()); |
449 | SetTrim(B1,Line); |
450 | } |
451 | if (!Line2.IsNull()) { |
452 | Line = new Geom2d_TrimmedCurve(Line2,0.,Precision::Infinite()); |
453 | SetTrim(B1,Line); |
454 | } |
455 | } |
456 | } |
457 | } |
458 | |
459 | //============================================================================= |
460 | //function : TrimBisector |
461 | //purpose : |
462 | //============================================================================= |
463 | Standard_Boolean MAT2d_Tool2d::TrimBisector |
464 | (const Handle(MAT_Bisector)& abisector) |
465 | { |
466 | Standard_Real param = abisector->FirstParameter(); |
467 | |
468 | #ifdef DEB |
469 | Standard_Boolean Affich = Standard_False; |
470 | if (Affich) cout<<"TRIM de "<<abisector->BisectorNumber()<<endl; |
471 | #endif |
472 | |
473 | Handle(Geom2d_TrimmedCurve) |
474 | bisector = Handle(Geom2d_TrimmedCurve) |
475 | ::DownCast(ChangeGeomBis(abisector->BisectorNumber()).ChangeValue()); |
476 | |
477 | if(bisector->BasisCurve()->IsPeriodic() && param == Precision::Infinite()) { |
c6541a0c |
478 | param = bisector->FirstParameter() + 2*M_PI; |
7fd59977 |
479 | } |
480 | if (param > bisector->BasisCurve()->LastParameter()) { |
481 | param = bisector->BasisCurve()->LastParameter(); |
482 | } |
483 | if(bisector->FirstParameter() == param) return Standard_False; |
484 | |
485 | bisector->SetTrim(bisector->FirstParameter(),param); |
486 | return Standard_True; |
487 | } |
488 | |
489 | //============================================================================= |
490 | //function : TrimBisector |
491 | //purpose : |
492 | //============================================================================= |
493 | Standard_Boolean MAT2d_Tool2d::TrimBisector |
494 | (const Handle(MAT_Bisector)& abisector, |
495 | const Standard_Integer apoint) |
496 | { |
497 | Standard_Real Param; |
498 | Handle(Geom2d_TrimmedCurve) |
499 | Bisector = Handle(Geom2d_TrimmedCurve):: |
500 | DownCast(ChangeGeomBis(abisector->BisectorNumber()).ChangeValue()); |
501 | |
502 | Handle(Bisector_Curve) Bis = Handle(Bisector_Curve):: |
503 | DownCast(Bisector->BasisCurve()); |
504 | |
505 | // Param = ParameterOnCurve(Bisector,theGeomPnts.Value(apoint)); |
506 | Param = Bis->Parameter(GeomPnt (apoint)); |
507 | |
508 | if (Bisector->BasisCurve()->IsPeriodic()) { |
c6541a0c |
509 | if (Bisector->FirstParameter() > Param) Param = Param + 2*M_PI; |
7fd59977 |
510 | } |
511 | if(Bisector->FirstParameter() >= Param)return Standard_False; |
512 | if(Bisector->LastParameter() < Param)return Standard_False; |
513 | Bisector->SetTrim(Bisector->FirstParameter(),Param); |
514 | |
515 | #ifdef DEB |
516 | Standard_Boolean Affich = Standard_False; |
517 | if (Affich) MAT2d_DrawCurve(Bisector,2); |
518 | #endif |
519 | |
520 | return Standard_True; |
521 | } |
522 | |
523 | //============================================================================= |
524 | //function : Projection |
525 | //purpose : |
526 | //============================================================================= |
527 | Standard_Boolean MAT2d_Tool2d::Projection (const Standard_Integer IEdge , |
528 | const gp_Pnt2d& PCom , |
529 | Standard_Real& Distance) |
530 | const |
531 | { |
532 | gp_Pnt2d PEdge; |
533 | Handle(Geom2d_Geometry) Elt = theCircuit->Value(IEdge); |
534 | Handle(Standard_Type) Type = Elt->DynamicType(); |
535 | Handle(Geom2d_TrimmedCurve) Curve; |
536 | Standard_Integer INext; |
7fd59977 |
537 | Standard_Real Eps = MAT2d_TOLCONF;//*10.; |
538 | |
539 | if (Type == STANDARD_TYPE(Geom2d_CartesianPoint)) { |
540 | PEdge = Handle(Geom2d_Point)::DownCast(Elt)->Pnt2d(); |
541 | Distance = PCom.Distance(PEdge); |
542 | } |
543 | else { |
544 | Distance = Precision::Infinite(); |
545 | Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Elt); |
546 | //----------------------------------------------------------------------- |
547 | // Calcul des parametres MinMax sur l edge si celui ci est lies a ses |
548 | // voisins par des connexions la courbe de calcul est limitee par |
549 | // celles_ci. |
550 | //----------------------------------------------------------------------- |
551 | Standard_Real ParamMin = Curve->FirstParameter(); |
552 | Standard_Real ParamMax = Curve->LastParameter(); |
553 | if (theCircuit->ConnexionOn(IEdge)) { |
554 | ParamMin = theCircuit->Connexion(IEdge)->ParameterOnSecond(); |
555 | } |
556 | INext = (IEdge == theCircuit->NumberOfItems()) ? 1 : (IEdge + 1); |
557 | if (theCircuit->ConnexionOn(INext)) { |
558 | ParamMax = theCircuit->Connexion(INext)->ParameterOnFirst(); |
559 | if (Curve->BasisCurve()->IsPeriodic()){ |
c6541a0c |
560 | ElCLib::AdjustPeriodic(0.,2*M_PI,Eps,ParamMin,ParamMax); |
7fd59977 |
561 | } |
562 | } |
563 | //--------------------------------------------------------------------- |
564 | // Constuction de la courbe pour les extremas et ajustement des bornes. |
565 | //--------------------------------------------------------------------- |
566 | Geom2dAdaptor_Curve C1(Curve); |
567 | GeomAbs_CurveType TypeC1 = C1.GetType(); |
568 | if (TypeC1 == GeomAbs_Circle) { |
569 | Standard_Real R = C1.Circle().Radius(); |
570 | Standard_Real EpsCirc = Eps; |
571 | if ( R < 1.) EpsCirc = Eps/R; |
c6541a0c |
572 | if (!((ParamMax - ParamMin + 2*EpsCirc) < 2*M_PI)) { |
7fd59977 |
573 | ParamMax = ParamMax + EpsCirc; ParamMin = ParamMin - EpsCirc; |
574 | } |
575 | } |
576 | else { |
577 | ParamMax = ParamMax + Eps; ParamMin = ParamMin - Eps; |
578 | } |
579 | //----------------------------------------------------- |
580 | // Calcul des extremas et stockage minimum de distance. |
581 | //----------------------------------------------------- |
582 | Extrema_ExtPC2d Extremas(PCom,C1,ParamMin,ParamMax); |
583 | if (Extremas.IsDone()){ |
584 | if (Extremas.NbExt() == 0 ) return Standard_False; // Pas de solution! |
585 | for (Standard_Integer i = 1; i <= Extremas.NbExt(); i++) { |
586 | if (Extremas.SquareDistance(i) < Distance * Distance) { |
7fd59977 |
587 | Distance = sqrt (Extremas.SquareDistance(i)); |
588 | } |
589 | } |
590 | } |
591 | else { |
592 | if (TypeC1 == GeomAbs_Circle) { |
593 | Distance = C1.Circle().Radius(); |
594 | } |
595 | } |
596 | } |
597 | return Standard_True; |
598 | } |
599 | |
600 | //============================================================================= |
601 | //function : IsSameDistance |
602 | // purpose : |
603 | //============================================================================= |
604 | Standard_Boolean MAT2d_Tool2d::IsSameDistance ( |
605 | const Handle(MAT_Bisector)& BisectorOne, |
606 | const Handle(MAT_Bisector)& BisectorTwo, |
607 | const gp_Pnt2d& PCom, |
608 | Standard_Real& Distance) const |
609 | { |
610 | TColStd_Array1OfReal Dist(1,4); |
611 | Standard_Integer IEdge1,IEdge2,IEdge3,IEdge4; |
612 | |
613 | IEdge1 = BisectorOne->FirstEdge() ->EdgeNumber(); |
614 | IEdge2 = BisectorOne->SecondEdge()->EdgeNumber(); |
615 | IEdge3 = BisectorTwo->FirstEdge() ->EdgeNumber(); |
616 | IEdge4 = BisectorTwo->SecondEdge()->EdgeNumber(); |
617 | |
618 | Projection(IEdge1,PCom,Dist(1)); |
619 | Projection(IEdge2,PCom,Dist(2)); |
620 | |
621 | if (IEdge3 == IEdge1) Dist(3) = Dist(1); |
622 | else if (IEdge3 == IEdge2) Dist(3) = Dist(2); |
623 | else Projection(IEdge3,PCom,Dist(3)); |
624 | |
625 | if (IEdge4 == IEdge1) Dist(4) = Dist(1); |
626 | else if (IEdge4 == IEdge2) Dist(4) = Dist(2); |
627 | else Projection(IEdge4,PCom,Dist(4)); |
628 | |
629 | #ifdef DEB |
630 | Standard_Boolean Affich = Standard_False; |
631 | if (Affich) |
632 | for (Standard_Integer j = 1; j <= 4;j++){ |
633 | cout <<"Distance number : "<<j<<" is :"<< Dist(j)<<endl; |
634 | } |
635 | #endif |
636 | |
637 | Standard_Real EpsDist = MAT2d_TOLCONF*100. ; |
638 | Distance = Dist(1); |
639 | for (Standard_Integer i = 1; i <= 4; i++){ |
640 | if (Abs(Dist(i) - Distance) > EpsDist) { |
641 | Distance = Precision::Infinite(); |
642 | return Standard_False; |
643 | } |
644 | } |
645 | return Standard_True; |
646 | } |
647 | |
648 | //============================================================================= |
649 | //function : IntersectBisector |
650 | //purpose : |
651 | //============================================================================= |
652 | Standard_Real MAT2d_Tool2d::IntersectBisector ( |
653 | const Handle(MAT_Bisector)& BisectorOne, |
654 | const Handle(MAT_Bisector)& BisectorTwo, |
655 | Standard_Integer& IntPnt) |
656 | { |
657 | Standard_Real Tolerance = MAT2d_TOLCONF; |
658 | Standard_Real Param1,Param2; |
659 | Standard_Real Parama,Paramb; |
1d47d8d0 |
660 | Standard_Real Distance = 0.,DistanceMini; |
7fd59977 |
661 | Standard_Boolean SolutionValide; |
662 | gp_Pnt2d PointSolution; |
663 | |
664 | Handle(Geom2d_TrimmedCurve) |
665 | Bisector1 = Handle(Geom2d_TrimmedCurve) |
666 | ::DownCast(ChangeGeomBis(BisectorOne->BisectorNumber()).ChangeValue()); |
667 | |
668 | Handle(Geom2d_TrimmedCurve) |
669 | Bisector2 = Handle(Geom2d_TrimmedCurve) |
670 | ::DownCast(ChangeGeomBis(BisectorTwo->BisectorNumber()).ChangeValue()); |
671 | |
672 | if(Bisector1.IsNull() || Bisector2.IsNull()) return Precision::Infinite(); |
673 | |
674 | //------------------------------------------------------------------------- |
675 | // Si les deux bissectrices separent des elements consecutifs et qu elles |
676 | // sont issues des connexions C1 et C2. |
677 | // Si C1 est la reverse de C2 ,alors les deux bissectrices sont issues |
678 | // du meme point. Dans ce cas l intersection n est pas validee. |
679 | //------------------------------------------------------------------------- |
680 | Standard_Integer IS1 = BisectorOne->SecondEdge()->EdgeNumber(); |
681 | Standard_Integer IS2 = BisectorTwo->SecondEdge()->EdgeNumber(); |
682 | Standard_Integer IF1 = BisectorOne->FirstEdge() ->EdgeNumber(); |
683 | Standard_Integer IF2 = BisectorTwo->FirstEdge() ->EdgeNumber(); |
684 | |
685 | if (AreNeighbours(IF1,IS1,NumberOfItems()) && |
686 | AreNeighbours(IF2,IS2,NumberOfItems()) && |
687 | theCircuit->ConnexionOn(IS2) && |
688 | theCircuit->ConnexionOn(IS1) ) { |
689 | Handle(MAT2d_Connexion) C1,C2; |
690 | C1 = theCircuit->Connexion(IS1); |
691 | C2 = theCircuit->Connexion(IS2); |
692 | if (C2->IndexFirstLine() == C1->IndexSecondLine() && |
693 | C1->IndexFirstLine() == C2->IndexSecondLine() ) |
694 | return Precision::Infinite(); |
695 | } |
696 | |
697 | // ----------------------------------------- |
698 | // Construction des domaines d intersection. |
699 | // ----------------------------------------- |
700 | IntRes2d_Domain Domain1 = Domain(Bisector1,Tolerance); |
701 | IntRes2d_Domain Domain2 = Domain(Bisector2,Tolerance); |
702 | |
703 | if (Domain1.LastParameter() - Domain1.FirstParameter() < Tolerance) |
704 | return Precision::Infinite(); |
705 | if (Domain2.LastParameter() - Domain2.FirstParameter() < Tolerance) |
706 | return Precision::Infinite(); |
707 | |
708 | #ifdef DEB |
709 | Standard_Boolean Affich = Standard_False; |
710 | if (Affich) { |
711 | cout<<endl; |
712 | cout<<"INTERSECTION de "<<BisectorOne->BisectorNumber()<< |
713 | " et de "<<BisectorTwo->BisectorNumber()<<endl; |
714 | cout<<" Bisector 1 : "<<endl; |
715 | // (Bisector1->BasisCurve())->Dump(-1,1); |
716 | cout<<endl; |
717 | Debug(Domain1.FirstParameter()); |
718 | Debug(Domain1.LastParameter()); |
719 | cout<<"-----------------"<<endl; |
720 | cout<<" Bisector 2 : "<<endl; |
721 | // (Bisector2->BasisCurve())->Dump(-1,1); |
722 | cout<<endl; |
723 | Debug(Domain2.FirstParameter()); |
724 | Debug(Domain2.LastParameter()); |
725 | cout<<"-----------------"<<endl; |
726 | } |
727 | #endif |
728 | |
729 | // ------------------------- |
730 | // Calcul de l intersection. |
731 | // ------------------------- |
732 | |
733 | Bisector_Inter Intersect; |
734 | Intersect.Perform (GeomBis(BisectorOne->BisectorNumber()),Domain1, |
735 | GeomBis(BisectorTwo->BisectorNumber()),Domain2, |
736 | Tolerance,Tolerance,Standard_True); |
737 | |
738 | // Geom2dInt_GInter Intersect; |
739 | // Intersect.Perform(Bisector1,Domain1,Bisector2,Domain2,Tolerance,Tolerance); |
740 | |
741 | // ------------------------------------------------------------------------- |
742 | // Exploitation du resultat de l intersection et selection du point solution |
743 | // equidistant des deux edges et le plus proche en parametre de l origine |
744 | // des bissectrices. |
745 | // ------------------------------------------------------------------------- |
746 | |
747 | if(!Intersect.IsDone()) return Precision::Infinite(); |
748 | |
749 | if(Intersect.IsEmpty()) return Precision::Infinite(); |
750 | |
751 | DistanceMini = Precision::Infinite(); |
752 | Param1 = Precision::Infinite(); |
753 | Param2 = Precision::Infinite(); |
754 | SolutionValide = Standard_False; |
755 | |
756 | if(Intersect.NbSegments() >= 1) { |
757 | Standard_Real MaxSegmentLength = 10.*Tolerance; |
758 | for (Standard_Integer i=1;i<=Intersect.NbSegments();i++) { |
759 | IntRes2d_IntersectionSegment Segment = Intersect.Segment(i); |
760 | Standard_Boolean PointRetenu = Standard_False; |
761 | gp_Pnt2d PointOnSegment; |
762 | // ---------------------------------------------------------------- |
763 | // Si les segments sont petits, recherche des points sur le segment |
764 | // equidistants des edges. |
765 | // ---------------------------------------------------------------- |
766 | if ((Segment.HasFirstPoint() && Segment.HasLastPoint())) { |
767 | gp_Pnt2d P1,P2; |
768 | Standard_Real SegmentLength; |
769 | P1 = Segment.FirstPoint().Value(); |
770 | P2 = Segment.LastPoint().Value(); |
771 | SegmentLength = P1.Distance(P2); |
772 | if (SegmentLength <= Tolerance) { |
773 | PointOnSegment = P1; |
774 | if(IsSameDistance(BisectorOne,BisectorTwo, |
775 | PointOnSegment,Distance)) |
776 | PointRetenu = Standard_True; |
777 | } |
778 | else if (SegmentLength <= MaxSegmentLength) { |
779 | gp_Dir2d Dir(P2.X()-P1.X(),P2.Y()-P1.Y()); |
780 | Standard_Real Dist = 0.; |
781 | while (Dist <= SegmentLength + Tolerance){ |
782 | PointOnSegment = P1.Translated(Dist*Dir); |
783 | if(IsSameDistance(BisectorOne,BisectorTwo, |
784 | PointOnSegment,Distance)) { |
785 | PointRetenu = Standard_True; |
786 | break; |
787 | } |
788 | Dist = Dist + Tolerance; |
789 | } |
790 | } |
791 | } |
792 | |
793 | // ---------------------------------------------------------------- |
794 | // Sauvegarde du point equidistant des edges de plus petit |
795 | // parametre sur les bissectrices. |
796 | // ---------------------------------------------------------------- |
797 | if(PointRetenu) { |
798 | Parama = Handle(Bisector_Curve)::DownCast(Bisector1->BasisCurve()) |
799 | ->Parameter(PointOnSegment); |
800 | Paramb = Handle(Bisector_Curve)::DownCast(Bisector2->BasisCurve()) |
801 | ->Parameter(PointOnSegment); |
802 | if(Parama < Param1 && Paramb < Param2) { |
803 | Param1 = Parama; |
804 | Param2 = Paramb; |
805 | DistanceMini = Distance; |
806 | PointSolution = PointOnSegment; |
807 | SolutionValide = Standard_True; |
808 | } |
809 | } |
810 | } |
811 | } |
812 | |
813 | if(Intersect.NbPoints() != 1) { |
814 | for(Standard_Integer i=1; i<=Intersect.NbPoints(); i++) { |
815 | if(IsSameDistance(BisectorOne,BisectorTwo, |
816 | Intersect.Point(i).Value(),Distance) && |
817 | Distance > Tolerance ) { |
818 | Parama = Intersect.Point(i).ParamOnFirst(); |
819 | Paramb = Intersect.Point(i).ParamOnSecond(); |
820 | if (Parama < Param1 && Paramb < Param2) { |
821 | Param1 = Parama; |
822 | Param2 = Paramb; |
823 | DistanceMini = Distance; |
824 | PointSolution = Intersect.Point(i).Value(); |
825 | SolutionValide = Standard_True; |
826 | } |
827 | } |
828 | } |
829 | } |
830 | else { |
831 | PointSolution = Intersect.Point(1).Value(); |
832 | Param1 = Intersect.Point(1).ParamOnFirst(); |
833 | Param2 = Intersect.Point(1).ParamOnSecond(); |
834 | SolutionValide = IsSameDistance(BisectorOne,BisectorTwo, |
835 | PointSolution,DistanceMini); |
836 | } |
837 | |
838 | if (!SolutionValide) return Precision::Infinite(); |
839 | theNumberOfPnts++; |
840 | theGeomPnts.Bind(theNumberOfPnts,PointSolution); |
841 | IntPnt = theNumberOfPnts; |
842 | |
843 | //----------------------------------------------------------------------- |
844 | // Si le point d intersection est quasi confondue avec une des extremites |
845 | // de l une ou l autre des bisectrices, l intersection n est pas validee. |
846 | // |
847 | // SAUF si une des bisectrices est issue d une connexion et que les |
848 | // edges separes par les bissectrices sont des voisines sur le contour |
849 | // initiales. |
850 | // en effet le milieu de la connexion P qui est l origine d une des |
851 | // bissectrices peut etre sur l autre bissectrice. |
852 | // P est donc point d intersection |
853 | // et la bissectrice issue de la connexion est de longueur nulle. |
854 | // (ex : un rectangle dans un rectangle ou la connexion est entre un coin |
855 | // et un cote). |
856 | //----------------------------------------------------------------------- |
857 | |
858 | Standard_Integer IndexEdge1,IndexEdge2,IndexEdge3,IndexEdge4; |
859 | Standard_Boolean ExtremiteControle = Standard_True; |
860 | |
861 | IndexEdge1 = BisectorOne->FirstEdge() ->EdgeNumber(); |
862 | IndexEdge2 = BisectorOne->SecondEdge()->EdgeNumber(); |
863 | IndexEdge3 = BisectorTwo->FirstEdge() ->EdgeNumber(); |
864 | IndexEdge4 = BisectorTwo->SecondEdge()->EdgeNumber(); |
865 | |
866 | if (theCircuit->ConnexionOn(IndexEdge2)){ |
867 | // -------------------------------------- |
868 | // BisectorOne est issue d une connexion. |
869 | // -------------------------------------- |
870 | if (AreNeighbours(IndexEdge1,IndexEdge2,NumberOfItems()) && |
871 | AreNeighbours(IndexEdge3,IndexEdge4,NumberOfItems()) && |
872 | IndexEdge2 == IndexEdge3 ){ |
873 | ExtremiteControle = Standard_False; |
874 | Param1 = Param1 + Tolerance; |
875 | } |
876 | } |
877 | |
878 | if (theCircuit->ConnexionOn(IndexEdge4)){ |
879 | // -------------------------------------- |
880 | // BisectorTwo est issue d une connexion. |
881 | // -------------------------------------- |
882 | if (AreNeighbours(IndexEdge1,IndexEdge2,NumberOfItems()) && |
883 | AreNeighbours(IndexEdge3,IndexEdge4,NumberOfItems()) && |
884 | IndexEdge2 == IndexEdge3 ){ |
885 | ExtremiteControle = Standard_False; |
886 | Param2 = Param2 + Tolerance; |
887 | } |
888 | } |
889 | |
890 | if (ExtremiteControle) { |
891 | if(Bisector1->StartPoint().Distance(PointSolution) < Tolerance || |
892 | Bisector2->StartPoint().Distance(PointSolution) < Tolerance ) |
893 | return Precision::Infinite(); |
894 | } |
895 | |
896 | if(BisectorOne->SecondParameter() < Precision::Infinite() && |
897 | BisectorOne->SecondParameter() < Param1*(1. - Tolerance )) |
898 | return Precision::Infinite(); |
899 | |
900 | if(BisectorTwo->FirstParameter() < Precision::Infinite() && |
901 | BisectorTwo->FirstParameter() < Param2*(1.- Tolerance)) |
902 | return Precision::Infinite(); |
903 | |
904 | BisectorOne->SecondParameter(Param1); |
905 | BisectorTwo->FirstParameter (Param2); |
906 | |
907 | #ifdef DEB |
908 | if (Affich) { |
909 | cout<<" coordonnees : "<<GeomPnt (IntPnt).X()<<" " |
910 | <<GeomPnt (IntPnt).Y()<<endl; |
911 | cout<<" parametres : "<<Param1<<" "<<Param2<<endl; |
912 | cout<<" distancemini : "<<DistanceMini<<endl; |
913 | } |
914 | #endif |
915 | |
916 | return DistanceMini; |
917 | } |
918 | |
919 | //============================================================================= |
920 | //function : Distance |
921 | //purpose : |
922 | //============================================================================= |
923 | Standard_Real MAT2d_Tool2d::Distance(const Handle(MAT_Bisector)& Bis, |
924 | const Standard_Real Param1, |
925 | const Standard_Real Param2) const |
926 | { |
927 | Standard_Real Dist = Precision::Infinite(); |
928 | |
929 | if (Param1 != Precision::Infinite() && Param2 != Precision::Infinite()) { |
930 | gp_Pnt2d P1 = GeomBis(Bis->BisectorNumber()).Value()->Value(Param1); |
931 | gp_Pnt2d P2 = GeomBis(Bis->BisectorNumber()).Value()->Value(Param2); |
932 | Dist = P1.Distance(P2); |
933 | } |
934 | return Dist; |
935 | } |
936 | |
937 | //============================================================================= |
938 | //function : Dump |
939 | //purpose : |
940 | //============================================================================= |
941 | #ifndef DEB |
942 | void MAT2d_Tool2d::Dump(const Standard_Integer , |
943 | const Standard_Integer ) const |
944 | { |
945 | Standard_NotImplemented::Raise(); |
946 | #else |
947 | void MAT2d_Tool2d::Dump(const Standard_Integer bisector, |
948 | const Standard_Integer) const |
949 | { |
950 | if(bisector == -1) return; |
951 | if(bisector > theNumberOfBisectors) return; |
952 | |
953 | Handle(Geom2d_Curve) thebisector = GeomBis(bisector).Value(); |
954 | |
955 | MAT2d_DrawCurve(thebisector,3); |
956 | |
957 | #endif |
958 | } |
959 | |
960 | |
961 | //============================================================================= |
962 | //function : GeomBis |
963 | //purpose : |
964 | //============================================================================= |
965 | const Bisector_Bisec& MAT2d_Tool2d::GeomBis (const Standard_Integer Index) |
966 | const |
967 | { |
968 | return theGeomBisectors.Find(Index); |
969 | } |
970 | |
971 | //============================================================================= |
972 | //function : ChangeGeomBis |
973 | //purpose : |
974 | //============================================================================= |
975 | Bisector_Bisec& MAT2d_Tool2d::ChangeGeomBis(const Standard_Integer Index) |
976 | { |
977 | return theGeomBisectors.ChangeFind(Index); |
978 | } |
979 | |
980 | |
981 | //============================================================================= |
982 | //function : GeomElt |
983 | //purpose : |
984 | //============================================================================= |
985 | Handle(Geom2d_Geometry) MAT2d_Tool2d::GeomElt(const Standard_Integer Index) |
986 | const |
987 | { |
988 | return theCircuit->Value(Index); |
989 | } |
990 | |
991 | |
992 | //============================================================================= |
993 | //function : GeomPnt |
994 | //purpose : |
995 | //============================================================================= |
996 | const gp_Pnt2d& MAT2d_Tool2d::GeomPnt(const Standard_Integer Index) const |
997 | { |
998 | return theGeomPnts.Find(Index); |
999 | } |
1000 | |
1001 | //============================================================================= |
1002 | //function : GeomVec |
1003 | //purpose : |
1004 | //============================================================================= |
1005 | const gp_Vec2d& MAT2d_Tool2d::GeomVec(const Standard_Integer Index)const |
1006 | { |
1007 | return theGeomVecs.Find(Index); |
1008 | } |
1009 | |
1010 | //============================================================================= |
1011 | //function : Circuit |
1012 | //purpose : |
1013 | //============================================================================= |
1014 | Handle(MAT2d_Circuit) MAT2d_Tool2d::Circuit()const |
1015 | { |
1016 | return theCircuit; |
1017 | } |
1018 | |
1019 | //============================================================================= |
1020 | //function : BisecFusion |
1021 | //purpose : |
1022 | //============================================================================= |
1023 | void MAT2d_Tool2d::BisecFusion(const Standard_Integer I1, |
1024 | const Standard_Integer I2) |
1025 | { |
1026 | Standard_Real DU,UL1,UF1; |
1027 | Handle(Geom2d_TrimmedCurve) Bisector1; |
1028 | Handle(Geom2d_TrimmedCurve) Bisector2; |
1029 | |
1030 | Bisector1 = Handle(Geom2d_TrimmedCurve)::DownCast(GeomBis(I1).Value()); |
1031 | Bisector2 = Handle(Geom2d_TrimmedCurve)::DownCast(GeomBis(I2).Value()); |
1032 | UF1 = Bisector1->FirstParameter(); |
1033 | UL1 = Bisector1->LastParameter(); |
1034 | |
1035 | Handle(Standard_Type) Type1 = Bisector1->BasisCurve()->DynamicType(); |
1036 | if (Type1 == STANDARD_TYPE(Bisector_BisecCC)) { |
1037 | //------------------------------------------------------------------------------------ |
1038 | // les bissectrice courbe/courbe sont construites avec un point de depart |
1039 | // elles ne peuvent pas etre trimes par un point se trouvant de l autre cote du |
1040 | // point de depart. |
1041 | // pour faire la fusion des deux bissectrices on reconstruit la bissectrice entre les |
1042 | // deux courbes avec comme point de depart le dernier point de la Bisector2. |
1043 | // on trime ensuite la courbe par le dernier point de Bisector1. |
1044 | //------------------------------------------------------------------------------------ |
1045 | Standard_Real Tolerance = MAT2d_TOLCONF; |
1046 | Bisector_Bisec Bis; |
1047 | gp_Vec2d VBid(1,0); |
1048 | gp_Pnt2d P2 = Bisector2->Value(Bisector2->LastParameter()); |
1049 | gp_Pnt2d P1 = Bisector1->Value(Bisector1->LastParameter()); |
1050 | Handle(Bisector_BisecCC) BCC1 = Handle(Bisector_BisecCC)::DownCast(Bisector1->BasisCurve()); |
1051 | |
1052 | Bis.Perform(BCC1->Curve(2), BCC1->Curve(1), P2, VBid, VBid, |
1053 | theDirection, Tolerance, Standard_False); |
1054 | |
1055 | Bisector1 = Handle(Geom2d_TrimmedCurve)::DownCast(Bis.Value()); |
1056 | BCC1 = Handle(Bisector_BisecCC) ::DownCast(Bisector1->BasisCurve()); |
1057 | UF1 = BCC1->FirstParameter(); |
1058 | UL1 = BCC1->Parameter(P1); |
1059 | Bisector1->SetTrim(UF1,UL1); |
1060 | theGeomBisectors.Bind(I1,Bis); |
1061 | } |
1062 | else { |
1063 | DU = Bisector2->LastParameter() - Bisector2->FirstParameter(); |
1064 | UF1 = UF1 - DU; |
1065 | |
1066 | Handle(Bisector_BisecAna) BAna = Handle(Bisector_BisecAna)::DownCast(Bisector1->BasisCurve()); |
1067 | //---------------------------- uncomment if new method Bisector_BisecAna::SetTrim(f,l) is not used |
1068 | // Handle(Geom2d_Curve) C2d = BAna->Geom2dCurve(); |
1069 | // Handle(Geom2d_TrimmedCurve) trimC2d = new Geom2d_TrimmedCurve(C2d, UF1, UL1); |
1070 | // BAna->Init(trimC2d); |
1071 | //--------------------------- end |
1072 | BAna->SetTrim(UF1,UL1); // put comment if SetTrim(f,l) is not used |
1073 | |
1074 | Bisector1->SetTrim(UF1,UL1); |
1075 | } |
1076 | } |
1077 | |
1078 | //============================================================================= |
1079 | //function : Type |
1080 | //purpose : |
1081 | //============================================================================= |
1082 | static Handle(Standard_Type) Type(const Handle(Geom2d_Geometry)& aGeom) |
1083 | { |
1084 | Handle(Standard_Type) type = aGeom->DynamicType(); |
1085 | Handle(Geom2d_Curve) curve; |
1086 | |
1087 | if (type == STANDARD_TYPE(Geom2d_TrimmedCurve)) { |
1088 | curve = Handle(Geom2d_TrimmedCurve)::DownCast(aGeom)->BasisCurve(); |
1089 | type = curve->DynamicType(); |
1090 | } |
1091 | return type; |
1092 | } |
1093 | |
1094 | //========================================================================== |
1095 | //function : AreNeighbours |
1096 | //purpose : Return TRUE si IEdge1 et IEdge2 correspondent a des elements |
1097 | // consecutifs sur un contour ferme de NbEdge elements. |
1098 | //========================================================================== |
1099 | Standard_Boolean AreNeighbours(const Standard_Integer IEdge1, |
1100 | const Standard_Integer IEdge2, |
1101 | const Standard_Integer NbEdge) |
1102 | { |
1103 | if (Abs(IEdge1 - IEdge2) == 1) return Standard_True; |
1104 | else if (Abs(IEdge1 - IEdge2) == NbEdge -1) return Standard_True; |
1105 | else return Standard_False; |
1106 | } |
1107 | |
1108 | //========================================================================== |
1109 | //function : SetTrim |
1110 | //purpose : |
1111 | //========================================================================== |
1112 | void SetTrim(Bisector_Bisec& Bis, Handle(Geom2d_Curve)& Line1) |
1113 | { |
1114 | Geom2dInt_GInter Intersect; |
1115 | Standard_Real Distance; |
1116 | Standard_Real Tolerance = MAT2d_TOLCONF; |
1117 | Handle(Geom2d_TrimmedCurve) Bisector = |
1118 | Handle(Geom2d_TrimmedCurve)::DownCast(Bis.ChangeValue()); |
1119 | |
1120 | IntRes2d_Domain Domain1 = Domain(Bisector,Tolerance); |
1121 | Standard_Real UB1 = Bisector->FirstParameter(); |
1122 | Standard_Real UB2 = Bisector->LastParameter(); |
1123 | |
1124 | gp_Pnt2d FirstPointBisector = Bisector->Value(UB1); |
1125 | Standard_Real UTrim = Precision::Infinite(); |
1126 | |
1127 | Geom2dAdaptor_Curve AdapBisector(Bisector); |
1128 | Geom2dAdaptor_Curve AdapLine1 (Line1); |
1129 | Intersect.Perform(AdapBisector, Domain1, |
1130 | AdapLine1, Tolerance, Tolerance); |
1131 | |
1132 | if (Intersect.IsDone() && !Intersect.IsEmpty()) { |
1133 | for (Standard_Integer i = 1; i <= Intersect.NbPoints(); i++) { |
1134 | gp_Pnt2d PInt = Intersect.Point(i).Value(); |
1135 | Distance = FirstPointBisector.Distance(PInt); |
1136 | if (Distance > 10.*Tolerance && |
1137 | Intersect.Point(i).ParamOnFirst() < UTrim ) { |
1138 | UTrim = Intersect.Point(i).ParamOnFirst(); |
1139 | } |
1140 | } |
1141 | } |
1142 | // ------------------------------------------------------------------------ |
1143 | // Restriction de la Bissectrice par le point d intersection de plus petit |
1144 | // parametre. |
1145 | // ------------------------------------------------------------------------ |
1146 | if (UTrim < UB2 && UTrim > UB1) Bisector->SetTrim(UB1,UTrim); |
1147 | } |
1148 | |
1149 | //========================================================================== |
1150 | //function : Domain |
1151 | //purpose : |
1152 | //========================================================================== |
1153 | IntRes2d_Domain Domain(const Handle(Geom2d_TrimmedCurve)& Bisector1, |
1154 | const Standard_Real Tolerance) |
1155 | { |
1156 | Standard_Real Param1 = Bisector1->FirstParameter(); |
1157 | Standard_Real Param2 = Bisector1->LastParameter(); |
1158 | if(Param2 > 10000.) { |
1159 | Param2 = 10000.; |
1160 | Handle(Standard_Type) Type1 = Type(Bisector1->BasisCurve()); |
1161 | Handle(Geom2d_Curve) BasisCurve; |
1162 | if (Type1 == STANDARD_TYPE(Bisector_BisecAna)) { |
1163 | BasisCurve = Handle(Bisector_BisecAna) |
1164 | ::DownCast(Bisector1->BasisCurve())->Geom2dCurve(); |
1165 | Type1 = BasisCurve->DynamicType(); |
1166 | } |
1167 | gp_Parab2d gpParabola; |
1168 | gp_Hypr2d gpHyperbola; |
1169 | Standard_Real Focus; |
1170 | Standard_Real Limit = 50000.; |
1171 | if (Type1 == STANDARD_TYPE(Geom2d_Parabola)) { |
1172 | gpParabola = Handle(Geom2d_Parabola)::DownCast(BasisCurve)->Parab2d(); |
1173 | Focus = gpParabola.Focal(); |
1174 | Standard_Real Val1 = Sqrt(Limit*Focus); |
1175 | Standard_Real Val2 = Sqrt(Limit*Limit); |
1176 | Param2 = (Val1 <= Val2 ? Val1:Val2); |
1177 | } |
1178 | else if (Type1 == STANDARD_TYPE(Geom2d_Hyperbola)) { |
1179 | gpHyperbola = Handle(Geom2d_Hyperbola)::DownCast(BasisCurve)->Hypr2d(); |
1180 | Standard_Real Majr = gpHyperbola.MajorRadius(); |
1181 | Standard_Real Minr = gpHyperbola.MinorRadius(); |
1182 | Standard_Real Valu1 = Limit/Majr; |
1183 | Standard_Real Valu2 = Limit/Minr; |
1184 | Standard_Real Val1 = Log(Valu1+Sqrt(Valu1*Valu1-1)); |
1185 | Standard_Real Val2 = Log(Valu2+Sqrt(Valu2*Valu2+1)); |
1186 | Param2 = (Val1 <= Val2 ? Val1:Val2); |
1187 | } |
1188 | } |
1189 | |
1190 | IntRes2d_Domain Domain1(Bisector1->Value(Param1),Param1,Tolerance, |
1191 | Bisector1->Value(Param2),Param2,Tolerance); |
1192 | if(Bisector1->BasisCurve()->IsPeriodic()) { |
c6541a0c |
1193 | Domain1.SetEquivalentParameters(0.,2.*M_PI); |
7fd59977 |
1194 | } |
1195 | return Domain1; |
1196 | } |
1197 | |
1198 | #ifdef DEB |
1199 | //========================================================================== |
1200 | //function : MAT2d_DrawCurve |
1201 | //purpose : Affichage d une courbe <aCurve> de Geom2d. dans une couleur |
1202 | // definie par <Indice>. |
1203 | // Indice = 1 jaune, |
1204 | // Indice = 2 bleu, |
1205 | // Indice = 3 rouge, |
1206 | // Indice = 4 vert. |
1207 | //========================================================================== |
1208 | void MAT2d_DrawCurve(const Handle(Geom2d_Curve)& aCurve, |
35e08fe8 |
1209 | const Standard_Integer /*Indice*/) |
7fd59977 |
1210 | { |
1211 | Handle(Standard_Type) type = aCurve->DynamicType(); |
1212 | Handle(Geom2d_Curve) curve,CurveDraw; |
1213 | #ifdef DRAW |
1214 | Handle(DrawTrSurf_Curve2d) dr; |
1215 | Draw_Color Couleur; |
1216 | #endif |
1217 | |
1218 | if (type == STANDARD_TYPE(Geom2d_TrimmedCurve)) { |
1219 | curve = Handle(Geom2d_TrimmedCurve)::DownCast(aCurve)->BasisCurve(); |
1220 | type = curve->DynamicType(); |
1221 | // PB de representation des courbes semi_infinies. |
1222 | gp_Parab2d gpParabola; |
1223 | gp_Hypr2d gpHyperbola; |
1224 | Standard_Real Focus; |
1225 | Standard_Real Limit = 50000.; |
1226 | Standard_Real delta = 400; |
1227 | |
1228 | // PB de representation des courbes semi_infinies. |
1229 | if (aCurve->LastParameter() == Precision::Infinite()) { |
1230 | |
1231 | if (type == STANDARD_TYPE(Geom2d_Parabola)) { |
1232 | gpParabola = Handle(Geom2d_Parabola)::DownCast(curve)->Parab2d(); |
1233 | Focus = gpParabola.Focal(); |
1234 | Standard_Real Val1 = Sqrt(Limit*Focus); |
1235 | Standard_Real Val2 = Sqrt(Limit*Limit); |
1236 | delta= (Val1 <= Val2 ? Val1:Val2); |
1237 | } |
1238 | else if (type == STANDARD_TYPE(Geom2d_Hyperbola)) { |
1239 | gpHyperbola = Handle(Geom2d_Hyperbola)::DownCast(curve)->Hypr2d(); |
1240 | Standard_Real Majr = gpHyperbola.MajorRadius(); |
1241 | Standard_Real Minr = gpHyperbola.MinorRadius(); |
1242 | Standard_Real Valu1 = Limit/Majr; |
1243 | Standard_Real Valu2 = Limit/Minr; |
1244 | Standard_Real Val1 = Log(Valu1+Sqrt(Valu1*Valu1-1)); |
1245 | Standard_Real Val2 = Log(Valu2+Sqrt(Valu2*Valu2+1)); |
1246 | delta = (Val1 <= Val2 ? Val1:Val2); |
1247 | } |
1248 | CurveDraw = new Geom2d_TrimmedCurve(aCurve, |
1249 | aCurve->FirstParameter(), |
1250 | aCurve->FirstParameter() + delta); |
1251 | } |
1252 | else { |
1253 | CurveDraw = aCurve; |
1254 | } |
1255 | // fin PB. |
1256 | } |
1257 | else { |
1258 | CurveDraw = aCurve; |
1259 | } |
1260 | |
1261 | #ifdef DRAW |
1262 | if (Indice == 1) Couleur = Draw_jaune; |
1263 | else if (Indice == 2) Couleur = Draw_bleu; |
1264 | else if (Indice == 3) Couleur = Draw_rouge; |
1265 | else if (Indice == 4) Couleur = Draw_vert; |
1266 | |
1267 | if (type == STANDARD_TYPE(Geom2d_Circle)) |
1268 | dr = new DrawTrSurf_Curve2d(CurveDraw,Couleur,30); |
1269 | else if (type == STANDARD_TYPE(Geom2d_Line)) |
1270 | dr = new DrawTrSurf_Curve2d(CurveDraw,Couleur,2); |
1271 | else |
1272 | dr = new DrawTrSurf_Curve2d(CurveDraw,Couleur,500); |
1273 | |
1274 | dout << dr; |
1275 | dout.Flush(); |
1276 | #endif |
1277 | } |
1278 | |
1279 | #endif |
1280 | |