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