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