7fd59977 |
1 | // File: IntTools_LineConstructor.cxx |
2 | // Created: Tue Feb 7 10:12:45 1995 |
3 | // Author: Jacques GOUSSARD |
4 | // Copyright: OPEN CASCADE 1995 |
5 | |
6 | #include <IntTools_LineConstructor.ixx> |
7 | |
8 | #include <GeomInt_LineTool.hxx> |
9 | #include <GeomInt_SequenceOfParameterAndOrientation.hxx> |
10 | #include <GeomInt_ParameterAndOrientation.hxx> |
11 | |
12 | #include <IntPatch_Point.hxx> |
13 | #include <IntPatch_GLine.hxx> |
14 | #include <IntPatch_WLine.hxx> |
15 | #include <IntPatch_ALine.hxx> |
16 | #include <IntSurf_Transition.hxx> |
17 | #include <TopAbs_Orientation.hxx> |
18 | |
19 | |
20 | #include <Precision.hxx> |
21 | |
22 | #include <gp_Pnt2d.hxx> |
23 | |
24 | #include <Adaptor2d_HCurve2d.hxx> |
25 | |
26 | #include <GeomAdaptor_HSurface.hxx> |
27 | #include <Standard_ConstructionError.hxx> |
28 | #include <IntSurf_Quadric.hxx> |
29 | #include <IntSurf_PntOn2S.hxx> |
30 | #include <ElCLib.hxx> |
31 | #include <GeomAbs_SurfaceType.hxx> |
32 | // |
33 | #include <TColStd_IndexedMapOfInteger.hxx> |
34 | |
35 | |
36 | //======================================================================= |
37 | //function : Recadre |
38 | //purpose : |
39 | //======================================================================= |
40 | static void Recadre(const Handle(GeomAdaptor_HSurface)& myHS1, |
41 | const Handle(GeomAdaptor_HSurface)& myHS2, |
42 | Standard_Real& u1, |
43 | Standard_Real& v1, |
44 | Standard_Real& u2, |
45 | Standard_Real& v2) |
46 | { |
47 | Standard_Boolean myHS1IsUPeriodic,myHS1IsVPeriodic; |
48 | const GeomAbs_SurfaceType typs1 = myHS1->GetType(); |
49 | switch (typs1) |
50 | { |
51 | case GeomAbs_Cylinder: |
52 | case GeomAbs_Cone: |
53 | case GeomAbs_Sphere: |
54 | { |
55 | myHS1IsUPeriodic = Standard_True; |
56 | myHS1IsVPeriodic = Standard_False; |
57 | break; |
58 | } |
59 | case GeomAbs_Torus: |
60 | { |
61 | myHS1IsUPeriodic = myHS1IsVPeriodic = Standard_True; |
62 | break; |
63 | } |
64 | default: |
65 | { |
66 | //-- Le cas de biparametrees periodiques est gere en amont |
67 | myHS1IsUPeriodic = myHS1IsVPeriodic = Standard_False; |
68 | break; |
69 | } |
70 | } |
71 | Standard_Boolean myHS2IsUPeriodic,myHS2IsVPeriodic; |
72 | const GeomAbs_SurfaceType typs2 = myHS2->GetType(); |
73 | switch (typs2) |
74 | { |
75 | case GeomAbs_Cylinder: |
76 | case GeomAbs_Cone: |
77 | case GeomAbs_Sphere: |
78 | { |
79 | myHS2IsUPeriodic = Standard_True; |
80 | myHS2IsVPeriodic = Standard_False; |
81 | break; |
82 | } |
83 | case GeomAbs_Torus: |
84 | { |
85 | myHS2IsUPeriodic = myHS2IsVPeriodic = Standard_True; |
86 | break; |
87 | } |
88 | default: |
89 | { |
90 | //-- Le cas de biparametrees periodiques est gere en amont |
91 | myHS2IsUPeriodic = myHS2IsVPeriodic = Standard_False; |
92 | break; |
93 | } |
94 | } |
95 | if(myHS1IsUPeriodic) { |
96 | const Standard_Real lmf = PI+PI; //-- myHS1->UPeriod(); |
97 | const Standard_Real f = myHS1->FirstUParameter(); |
98 | const Standard_Real l = myHS1->LastUParameter(); |
99 | while(u1 < f) { u1+=lmf; } |
100 | while(u1 > l) { u1-=lmf; } |
101 | } |
102 | if(myHS1IsVPeriodic) { |
103 | const Standard_Real lmf = PI+PI; //-- myHS1->VPeriod(); |
104 | const Standard_Real f = myHS1->FirstVParameter(); |
105 | const Standard_Real l = myHS1->LastVParameter(); |
106 | while(v1 < f) { v1+=lmf; } |
107 | while(v1 > l) { v1-=lmf; } |
108 | } |
109 | if(myHS2IsUPeriodic) { |
110 | const Standard_Real lmf = PI+PI; //-- myHS2->UPeriod(); |
111 | const Standard_Real f = myHS2->FirstUParameter(); |
112 | const Standard_Real l = myHS2->LastUParameter(); |
113 | while(u2 < f) { u2+=lmf; } |
114 | while(u2 > l) { u2-=lmf; } |
115 | } |
116 | if(myHS2IsVPeriodic) { |
117 | const Standard_Real lmf = PI+PI; //-- myHS2->VPeriod(); |
118 | const Standard_Real f = myHS2->FirstVParameter(); |
119 | const Standard_Real l = myHS2->LastVParameter(); |
120 | while(v2 < f) { v2+=lmf; } |
121 | while(v2 > l) { v2-=lmf; } |
122 | } |
123 | } |
124 | |
125 | |
126 | //======================================================================= |
127 | //function : Parameters |
128 | //purpose : |
129 | //======================================================================= |
130 | static void Parameters(const Handle(GeomAdaptor_HSurface)& myHS1, |
131 | const Handle(GeomAdaptor_HSurface)& myHS2, |
132 | const gp_Pnt& Ptref, |
133 | Standard_Real& U1, |
134 | Standard_Real& V1, |
135 | Standard_Real& U2, |
136 | Standard_Real& V2) |
137 | { |
138 | IntSurf_Quadric quad1,quad2; |
139 | switch (myHS1->Surface().GetType()) |
140 | { |
141 | case GeomAbs_Plane: quad1.SetValue(myHS1->Surface().Plane()); break; |
142 | case GeomAbs_Cylinder: quad1.SetValue(myHS1->Surface().Cylinder()); break; |
143 | case GeomAbs_Cone: quad1.SetValue(myHS1->Surface().Cone()); break; |
144 | case GeomAbs_Sphere: quad1.SetValue(myHS1->Surface().Sphere()); break; |
145 | default: Standard_ConstructionError::Raise("IntTools_LineConstructor::Parameters"); |
146 | } |
147 | switch (myHS2->Surface().GetType()) |
148 | { |
149 | case GeomAbs_Plane: quad2.SetValue(myHS2->Surface().Plane()); break; |
150 | case GeomAbs_Cylinder: quad2.SetValue(myHS2->Surface().Cylinder()); break; |
151 | case GeomAbs_Cone: quad2.SetValue(myHS2->Surface().Cone()); break; |
152 | case GeomAbs_Sphere: quad2.SetValue(myHS2->Surface().Sphere()); break; |
153 | default: Standard_ConstructionError::Raise("IntTools_LineConstructor::Parameters"); |
154 | } |
155 | quad1.Parameters(Ptref,U1,V1); |
156 | quad2.Parameters(Ptref,U2,V2); |
157 | } |
158 | |
159 | |
160 | //======================================================================= |
161 | //function : Perform |
162 | //purpose : |
163 | //======================================================================= |
164 | void IntTools_LineConstructor::Perform(const Handle(IntPatch_Line)& L) |
165 | { |
166 | Standard_Integer i,nbvtx; |
167 | Standard_Real firstp,lastp; |
168 | const Standard_Real Tol = Precision::PConfusion() * 35.0; |
169 | |
170 | const IntPatch_IType typl = L->ArcType(); |
171 | if(typl == IntPatch_Analytic) |
172 | { |
173 | Standard_Real u1,v1,u2,v2; |
174 | Handle(IntPatch_ALine)& ALine = *((Handle(IntPatch_ALine) *)&L); |
175 | seqp.Clear(); |
176 | nbvtx = GeomInt_LineTool::NbVertex(L); |
177 | for(i=1;i<nbvtx;i++) |
178 | { |
179 | firstp = GeomInt_LineTool::Vertex(L,i).ParameterOnLine(); |
180 | lastp = GeomInt_LineTool::Vertex(L,i+1).ParameterOnLine(); |
181 | if(firstp!=lastp) |
182 | { |
183 | const Standard_Real pmid = (firstp+lastp)*0.5; |
184 | const gp_Pnt Pmid = ALine->Value(pmid); |
185 | Parameters(myHS1,myHS2,Pmid,u1,v1,u2,v2); |
186 | Recadre(myHS1,myHS2,u1,v1,u2,v2); |
187 | const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol); |
188 | if(in1 != TopAbs_OUT) { |
189 | const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol); |
190 | if(in2 != TopAbs_OUT) { |
191 | seqp.Append(firstp); |
192 | seqp.Append(lastp); |
193 | } |
194 | } |
195 | } |
196 | } |
197 | done = Standard_True; |
198 | return; |
199 | } |
200 | else if(typl == IntPatch_Walking) |
201 | { |
202 | Standard_Real u1,v1,u2,v2; |
203 | Handle(IntPatch_WLine)& WLine = *((Handle(IntPatch_WLine) *)&L); |
204 | seqp.Clear(); |
205 | nbvtx = GeomInt_LineTool::NbVertex(L); |
206 | for(i=1;i<nbvtx;i++) |
207 | { |
208 | firstp = GeomInt_LineTool::Vertex(L,i).ParameterOnLine(); |
209 | lastp = GeomInt_LineTool::Vertex(L,i+1).ParameterOnLine(); |
210 | if(firstp!=lastp) |
211 | { |
212 | if(lastp != firstp+1) |
213 | { |
214 | const Standard_Integer pmid = (Standard_Integer )( (firstp+lastp)/2); |
215 | const IntSurf_PntOn2S& Pmid = WLine->Point(pmid); |
216 | Pmid.Parameters(u1,v1,u2,v2); |
217 | Recadre(myHS1,myHS2,u1,v1,u2,v2); |
218 | const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol); |
219 | if(in1 != TopAbs_OUT) { //-- !=ON donne Pb |
220 | const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol); |
221 | if(in2 != TopAbs_OUT) { //-- !=ON |
222 | seqp.Append(firstp); |
223 | seqp.Append(lastp); |
224 | } |
225 | } |
226 | } |
227 | else |
228 | { |
229 | const IntSurf_PntOn2S& Pfirst = WLine->Point((Standard_Integer)(firstp)); |
230 | Pfirst.Parameters(u1,v1,u2,v2); |
231 | Recadre(myHS1,myHS2,u1,v1,u2,v2); |
232 | TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol); |
233 | if(in1 != TopAbs_OUT) { //-- !=ON donne Pb |
234 | TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol); |
235 | if(in2 != TopAbs_OUT) { //-- !=ON |
236 | const IntSurf_PntOn2S& Plast = WLine->Point((Standard_Integer)(lastp)); |
237 | Plast.Parameters(u1,v1,u2,v2); |
238 | Recadre(myHS1,myHS2,u1,v1,u2,v2); |
239 | in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol); |
240 | if(in1 != TopAbs_OUT) { //-- !=ON donne Pb |
241 | in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol); |
242 | if(in2 != TopAbs_OUT) { |
243 | seqp.Append(firstp); |
244 | seqp.Append(lastp); |
245 | } |
246 | } |
247 | } |
248 | } |
249 | |
250 | } |
251 | } |
252 | } |
253 | //XX |
254 | // 904/L7 |
255 | // |
256 | // The One resulting curve consists of 7 segments that are |
257 | // connected between each other. |
258 | // The aim of the block is to reject these segments and have |
259 | // one segment instead of 7. |
260 | // The other reason to do that is value of TolReached3D=49. |
261 | // Why -? It is not known yet. |
262 | // PKV 22.Apr.2002 |
263 | // |
264 | const GeomAbs_SurfaceType aST1 = myHS1->Surface().GetType(); |
265 | const GeomAbs_SurfaceType aST2 = myHS2->Surface().GetType(); |
266 | if ((aST1==GeomAbs_Plane && aST2==GeomAbs_SurfaceOfExtrusion) || |
267 | (aST2==GeomAbs_Plane && aST1==GeomAbs_SurfaceOfExtrusion)) |
268 | { |
269 | TColStd_IndexedMapOfInteger aMap; |
270 | TColStd_SequenceOfReal aSeqTmp; |
271 | |
272 | Standard_Integer aNb, anIndex, aNbTmp, jx; |
273 | |
274 | aNb=seqp.Length(); |
275 | for(i=1; i<=aNb;++i) { |
276 | lastp =seqp(i); |
277 | anIndex=(Standard_Integer)lastp; |
278 | if (!aMap.Contains(anIndex)){ |
279 | aMap.Add(anIndex); |
280 | aSeqTmp.Append(lastp); |
281 | } |
282 | else { |
283 | aNbTmp=aSeqTmp.Length(); |
284 | aSeqTmp.Remove(aNbTmp); |
285 | } |
286 | } |
287 | // |
288 | seqp.Clear(); |
289 | // |
290 | aNb=aSeqTmp.Length()/2; |
291 | for(i=1; i<=aNb;++i) { |
292 | jx=2*i; |
293 | firstp=aSeqTmp(jx-1); |
294 | lastp =aSeqTmp(jx); |
295 | seqp.Append(firstp); |
296 | seqp.Append(lastp); |
297 | } |
298 | } |
299 | ////XX |
300 | done = Standard_True; |
301 | return; |
302 | } |
303 | else if (typl != IntPatch_Restriction) |
304 | { |
305 | Standard_Real u1,v1,u2,v2; |
306 | Handle(IntPatch_GLine)& GLine = *((Handle(IntPatch_GLine) *)&L); |
307 | seqp.Clear(); |
308 | nbvtx = GeomInt_LineTool::NbVertex(L); |
309 | Standard_Boolean intrvtested = Standard_False; |
310 | for(i=1;i<nbvtx;i++) |
311 | { |
312 | firstp = GeomInt_LineTool::Vertex(L,i).ParameterOnLine(); |
313 | lastp = GeomInt_LineTool::Vertex(L,i+1).ParameterOnLine(); |
314 | if(Abs(firstp-lastp)>Precision::PConfusion()) |
315 | { |
316 | intrvtested = Standard_True; |
317 | const Standard_Real pmid = (firstp+lastp)*0.5; |
318 | gp_Pnt Pmid; |
319 | switch (typl) |
320 | { |
321 | case IntPatch_Lin: Pmid = ElCLib::Value(pmid,GLine->Line()); break; |
322 | case IntPatch_Circle: Pmid = ElCLib::Value(pmid,GLine->Circle()); break; |
323 | case IntPatch_Ellipse: Pmid = ElCLib::Value(pmid,GLine->Ellipse()); break; |
324 | case IntPatch_Hyperbola: Pmid = ElCLib::Value(pmid,GLine->Hyperbola()); break; |
325 | case IntPatch_Parabola: Pmid = ElCLib::Value(pmid,GLine->Parabola()); break; |
326 | } |
327 | Parameters(myHS1,myHS2,Pmid,u1,v1,u2,v2); |
328 | Recadre(myHS1,myHS2,u1,v1,u2,v2); |
329 | const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol); |
330 | if(in1 != TopAbs_OUT) { |
331 | const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol); |
332 | if(in2 != TopAbs_OUT) { |
333 | seqp.Append(firstp); |
334 | seqp.Append(lastp); |
335 | } |
336 | } |
337 | } |
338 | } |
339 | |
340 | if(typl == IntPatch_Circle || typl == IntPatch_Ellipse) |
341 | { |
342 | firstp = GeomInt_LineTool::Vertex(L,nbvtx).ParameterOnLine(); |
343 | lastp = PI + PI + GeomInt_LineTool::Vertex(L,1).ParameterOnLine(); |
344 | const Standard_Real cadrinf = GeomInt_LineTool::FirstParameter(L); |
345 | const Standard_Real cadrsup = GeomInt_LineTool::LastParameter(L); |
346 | Standard_Real acadr = (firstp+lastp)*0.5; |
347 | while(acadr < cadrinf) { acadr+=PI+PI; } |
348 | while(acadr > cadrsup) { acadr-=PI+PI; } |
349 | if(acadr>=cadrinf && acadr<=cadrsup) |
350 | { |
351 | if(Abs(firstp-lastp)>Precision::PConfusion()) |
352 | { |
353 | intrvtested = Standard_True; |
354 | const Standard_Real pmid = (firstp+lastp)*0.5; |
355 | gp_Pnt Pmid; |
356 | if (typl == IntPatch_Circle) |
357 | Pmid = ElCLib::Value(pmid,GLine->Circle()); |
358 | else |
359 | Pmid = ElCLib::Value(pmid,GLine->Ellipse()); |
360 | Parameters(myHS1,myHS2,Pmid,u1,v1,u2,v2); |
361 | Recadre(myHS1,myHS2,u1,v1,u2,v2); |
362 | const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol); |
363 | if(in1 != TopAbs_OUT) { |
364 | const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol); |
365 | if(in2 != TopAbs_OUT) { |
366 | seqp.Append(firstp); |
367 | seqp.Append(lastp); |
368 | } |
369 | } |
370 | } |
371 | } |
372 | } |
373 | if (!intrvtested) { |
374 | // on garde a priori. Il faudrait un point 2d sur chaque |
375 | // surface pour prendre la decision. Sera fait dans |
376 | // l`appelant |
377 | seqp.Append(GeomInt_LineTool::FirstParameter(L)); |
378 | seqp.Append(GeomInt_LineTool::LastParameter(L)); |
379 | } |
380 | // |
381 | //modified by NIZNHY-PKV Mon Jan 21 17:02:12 2002 f |
382 | // |
383 | // Unite neighbouring intervals if it's possible. |
384 | // It is valid when 3D intersection curve does not go through |
385 | // the apex on surface. So for the moment we take into account |
386 | // Plane and Cylinder - surfaces that do not contain an apex. |
387 | // by NIZNHY-PKV Tue Jan 22 14:00:51 2002 |
388 | |
389 | const GeomAbs_SurfaceType aST1 = myHS1->Surface().GetType(); |
390 | const GeomAbs_SurfaceType aST2 = myHS2->Surface().GetType(); |
391 | if ((aST1==GeomAbs_Plane || aST1==GeomAbs_Cylinder) && |
392 | (aST2==GeomAbs_Plane || aST2==GeomAbs_Cylinder)) |
393 | { |
394 | if(typl == IntPatch_Circle || typl == IntPatch_Ellipse) |
395 | { |
396 | Standard_Integer aNbParts = seqp.Length()/2; |
397 | // |
398 | if (aNbParts > 1) |
399 | { |
400 | Standard_Integer j, i2, j2; |
401 | Standard_Real aFi = seqp(1), aLi, aFj, aLj, aF, aL; |
402 | TColStd_SequenceOfReal aSeq; |
403 | aSeq.Append(aFi); |
404 | for (i=1; i<aNbParts; ++i) |
405 | { |
406 | j=i+1; |
407 | i2=2*i; |
408 | j2=2*j; |
409 | |
410 | aFi=seqp(i2-1); |
411 | aLi=seqp(i2); |
412 | |
413 | aFj=seqp(j2-1); |
414 | aLj=seqp(j2); |
415 | |
416 | if (fabs (aFj-aLi) < Tol) |
417 | { |
418 | aL=aLj; |
419 | } |
420 | else |
421 | { |
422 | aL=aLi; |
423 | aSeq.Append(aL); |
424 | aF=aFj; |
425 | aSeq.Append(aF); |
426 | } |
427 | } |
428 | aSeq.Append(aLj); |
429 | // |
430 | seqp.Clear(); |
431 | aNbParts=aSeq.Length(); |
432 | for (i=1; i<=aNbParts; ++i) |
433 | { |
434 | aF=aSeq(i); |
435 | seqp.Append(aF); |
436 | } |
437 | } |
438 | } |
439 | } |
440 | //modified by NIZNHY-PKV Mon Jan 21 17:02:17 2002 t |
441 | // |
442 | done =Standard_True; |
443 | return; |
444 | } |
445 | |
446 | done = Standard_False; |
447 | seqp.Clear(); |
448 | nbvtx = GeomInt_LineTool::NbVertex(L); |
449 | if (nbvtx == 0) { // on garde a priori. Il faudrait un point 2d sur chaque |
450 | // surface pour prendre la decision. Sera fait dans |
451 | // l`appelant |
452 | seqp.Append(GeomInt_LineTool::FirstParameter(L)); |
453 | seqp.Append(GeomInt_LineTool::LastParameter(L)); |
454 | done = Standard_True; |
455 | return; |
456 | } |
457 | |
458 | GeomInt_SequenceOfParameterAndOrientation seqpss; |
459 | TopAbs_Orientation or1=TopAbs_FORWARD,or2=TopAbs_FORWARD; |
460 | |
461 | for (i=1; i<=nbvtx; i++) |
462 | { |
463 | const IntPatch_Point& thevtx = GeomInt_LineTool::Vertex(L,i); |
464 | const Standard_Real prm = thevtx.ParameterOnLine(); |
465 | if (thevtx.IsOnDomS1()) |
466 | { |
467 | switch (thevtx.TransitionLineArc1().TransitionType()) |
468 | { |
469 | case IntSurf_In: or1 = TopAbs_FORWARD; break; |
470 | case IntSurf_Out: or1 = TopAbs_REVERSED; break; |
471 | case IntSurf_Touch: or1 = TopAbs_INTERNAL; break; |
472 | case IntSurf_Undecided: or1 = TopAbs_INTERNAL; break; |
473 | } |
474 | } |
475 | else |
476 | or1 = TopAbs_INTERNAL; |
477 | |
478 | if (thevtx.IsOnDomS2()) |
479 | { |
480 | switch (thevtx.TransitionLineArc2().TransitionType()) |
481 | { |
482 | case IntSurf_In: or2 = TopAbs_FORWARD; break; |
483 | case IntSurf_Out: or2 = TopAbs_REVERSED; break; |
484 | case IntSurf_Touch: or2 = TopAbs_INTERNAL; break; |
485 | case IntSurf_Undecided: or2 = TopAbs_INTERNAL; break; |
486 | } |
487 | } |
488 | else |
489 | or2 = TopAbs_INTERNAL; |
490 | |
491 | const Standard_Integer nbinserted = seqpss.Length(); |
492 | Standard_Boolean inserted = Standard_False; |
493 | for (Standard_Integer j=1; j<=nbinserted;j++) |
494 | { |
495 | if (Abs(prm-seqpss(j).Parameter()) <= Tol) |
496 | { |
497 | // on cumule |
498 | GeomInt_ParameterAndOrientation& valj = seqpss.ChangeValue(j); |
499 | if (or1 != TopAbs_INTERNAL) { |
500 | if (valj.Orientation1() != TopAbs_INTERNAL) { |
501 | if (or1 != valj.Orientation1()) { |
502 | valj.SetOrientation1(TopAbs_INTERNAL); |
503 | } |
504 | } |
505 | else { |
506 | valj.SetOrientation1(or1); |
507 | } |
508 | } |
509 | |
510 | if (or2 != TopAbs_INTERNAL) { |
511 | if (valj.Orientation2() != TopAbs_INTERNAL) { |
512 | if (or2 != valj.Orientation2()) { |
513 | valj.SetOrientation2(TopAbs_INTERNAL); |
514 | } |
515 | } |
516 | else { |
517 | valj.SetOrientation2(or2); |
518 | } |
519 | } |
520 | inserted = Standard_True; |
521 | break; |
522 | } |
523 | |
524 | if (prm < seqpss(j).Parameter()-Tol ) { |
525 | // on insere avant la position j |
526 | seqpss.InsertBefore(j,GeomInt_ParameterAndOrientation(prm,or1,or2)); |
527 | inserted = Standard_True; |
528 | break; |
529 | } |
530 | |
531 | } |
532 | if (!inserted) { |
533 | seqpss.Append(GeomInt_ParameterAndOrientation(prm,or1,or2)); |
534 | } |
535 | } |
536 | |
537 | // on determine l`etat en debut de ligne |
538 | Standard_Boolean trim = Standard_False; |
539 | Standard_Boolean dansS1 = Standard_False; |
540 | Standard_Boolean dansS2 = Standard_False; |
541 | |
542 | nbvtx = seqpss.Length(); |
543 | for (i=1; i<= nbvtx; i++) |
544 | { |
545 | or1 = seqpss(i).Orientation1(); |
546 | if (or1 != TopAbs_INTERNAL) |
547 | { |
548 | trim = Standard_True; |
549 | dansS1 = (or1 != TopAbs_FORWARD); |
550 | break; |
551 | } |
552 | } |
553 | |
554 | if (i > nbvtx) |
555 | { |
556 | Standard_Real U,V; |
557 | for (i=1; i<=GeomInt_LineTool::NbVertex(L); i++ ) |
558 | { |
559 | if (!GeomInt_LineTool::Vertex(L,i).IsOnDomS1() ) |
560 | { |
561 | GeomInt_LineTool::Vertex(L,i).ParametersOnS1(U,V); |
562 | gp_Pnt2d PPCC(U,V); |
563 | if (myDom1->Classify(PPCC,Tol) == TopAbs_OUT) { |
564 | done = Standard_True; |
565 | return; |
566 | } |
567 | break; |
568 | } |
569 | } |
570 | dansS1 = Standard_True; // on garde dans le doute |
571 | } |
572 | |
573 | for (i=1; i<= nbvtx; i++) |
574 | { |
575 | or2 = seqpss(i).Orientation2(); |
576 | if (or2 != TopAbs_INTERNAL) |
577 | { |
578 | trim = Standard_True; |
579 | dansS2 = (or2 != TopAbs_FORWARD); |
580 | break; |
581 | } |
582 | } |
583 | |
584 | if (i > nbvtx) |
585 | { |
586 | Standard_Real U,V; |
587 | for (i=1; i<=GeomInt_LineTool::NbVertex(L); i++ ) |
588 | { |
589 | if (!GeomInt_LineTool::Vertex(L,i).IsOnDomS2() ) |
590 | { |
591 | GeomInt_LineTool::Vertex(L,i).ParametersOnS2(U,V); |
592 | if (myDom2->Classify(gp_Pnt2d(U,V),Tol) == TopAbs_OUT) { |
593 | done = Standard_True; |
594 | return; |
595 | } |
596 | break; |
597 | } |
598 | } |
599 | dansS2 = Standard_True; // on garde dans le doute |
600 | } |
601 | |
602 | if (!trim) { // on a necessairement dansS1 == dansS2 == Standard_True |
603 | seqp.Append(GeomInt_LineTool::FirstParameter(L)); |
604 | seqp.Append(GeomInt_LineTool::LastParameter(L)); |
605 | done = Standard_True; |
606 | return; |
607 | } |
608 | |
609 | // On epluche la sequence seqpss pour constituer les bouts valides |
610 | // et les stocker dans seqp(2*i+1) et seqp(2*i+2) |
611 | |
612 | Standard_Real thefirst = GeomInt_LineTool::FirstParameter(L); |
613 | Standard_Real thelast = GeomInt_LineTool::LastParameter(L); |
614 | firstp = thefirst; |
615 | |
616 | for (i=1; i<=nbvtx; i++) |
617 | { |
618 | or1 = seqpss(i).Orientation1(); |
619 | or2 = seqpss(i).Orientation2(); |
620 | if (dansS1 && dansS2) |
621 | { |
622 | if (or1 == TopAbs_REVERSED) |
623 | dansS1 = Standard_False; |
624 | /*else if (or1 == TopAbs_FORWARD) { |
625 | }*/ |
626 | if (or2 == TopAbs_REVERSED) |
627 | dansS2 = Standard_False; |
628 | /*else if (or2 == TopAbs_FORWARD) { |
629 | }*/ |
630 | if (!dansS1 || !dansS2) |
631 | { |
632 | lastp = seqpss(i).Parameter(); |
633 | Standard_Real stofirst = Max(firstp, thefirst); |
634 | Standard_Real stolast = Min(lastp, thelast) ; |
635 | |
636 | if (stolast > stofirst) { |
637 | seqp.Append(stofirst); |
638 | seqp.Append(stolast); |
639 | } |
640 | if (lastp > thelast) |
641 | break; |
642 | } |
643 | } |
644 | else |
645 | { |
646 | if (dansS1) |
647 | { |
648 | if (or1 == TopAbs_REVERSED) |
649 | dansS1 = Standard_False; |
650 | /*else if (or1 == TopAbs_FORWARD) { |
651 | }*/ |
652 | } |
653 | else |
654 | { |
655 | if (or1 == TopAbs_FORWARD) |
656 | dansS1 = Standard_True; |
657 | /*else if (or1 == TopAbs_REVERSED) { |
658 | }*/ |
659 | } |
660 | if (dansS2) |
661 | { |
662 | if (or2 == TopAbs_REVERSED) |
663 | dansS2 = Standard_False; |
664 | /*else if (or2 == TopAbs_FORWARD) { |
665 | }*/ |
666 | } |
667 | else |
668 | { |
669 | if (or2 == TopAbs_FORWARD) |
670 | dansS2 = Standard_True; |
671 | /*else if (or2 == TopAbs_REVERSED) { |
672 | }*/ |
673 | } |
674 | if (dansS1 && dansS2) |
675 | firstp = seqpss(i).Parameter(); |
676 | } |
677 | } |
678 | |
679 | // le petit dernier a rajouter |
680 | if (dansS1 && dansS2) |
681 | { |
682 | lastp = thelast; |
683 | firstp = Max(firstp,thefirst); |
684 | if (lastp > firstp) { |
685 | seqp.Append(firstp); |
686 | seqp.Append(lastp); |
687 | } |
688 | } |
689 | done = Standard_True; |
690 | } |
691 | |
692 | |
693 | //======================================================================= |
694 | //function : PeriodicLine |
695 | //purpose : |
696 | //======================================================================= |
697 | void IntTools_LineConstructor::PeriodicLine (const Handle(IntPatch_Line)& L) const |
698 | { |
699 | const IntPatch_IType typl = L->ArcType(); |
700 | if (typl != IntPatch_Circle && typl != IntPatch_Ellipse) |
701 | return; |
702 | |
703 | const Standard_Real Tol = Precision::PConfusion(); |
704 | Handle(IntPatch_GLine) glin = Handle(IntPatch_GLine)::DownCast(L); |
705 | Standard_Integer i,j,nbvtx = glin->NbVertex(); |
706 | for (i=1; i<=nbvtx; i++) |
707 | { |
708 | IntPatch_Point thevtx = glin->Vertex(i); |
709 | const Standard_Real prm = thevtx.ParameterOnLine(); |
710 | Standard_Boolean changevtx = Standard_False; |
711 | if (thevtx.IsOnDomS1() || thevtx.IsOnDomS2()) |
712 | { |
713 | for (j=1; j<=nbvtx; j++) |
714 | { |
715 | if (j!=i) |
716 | { |
717 | const IntPatch_Point& thevtxbis = glin->Vertex(j); |
718 | const Standard_Real prmbis = thevtxbis.ParameterOnLine(); |
719 | if (Abs(prm-prmbis) <= Tol) |
720 | { |
721 | Standard_Real u,v; |
722 | gp_Pnt2d p2d; |
723 | if (thevtx.IsOnDomS1() && thevtxbis.IsOnDomS1() && |
724 | thevtxbis.TransitionLineArc1().TransitionType()==IntSurf_In) |
725 | { |
726 | p2d = thevtx.ArcOnS1()->Value(thevtx.ParameterOnArc1()); |
727 | u = p2d.X(); v = p2d.Y(); |
728 | p2d = thevtxbis.ArcOnS1()->Value(thevtxbis.ParameterOnArc1()); |
729 | if (Abs(u-p2d.X()) > Tol || Abs(v-p2d.Y()) > Tol) |
730 | { |
731 | changevtx = Standard_True; |
732 | break; |
733 | } |
734 | } |
735 | if (thevtx.IsOnDomS2() && thevtxbis.IsOnDomS2() && |
736 | thevtxbis.TransitionLineArc2().TransitionType()==IntSurf_In) |
737 | { |
738 | p2d = thevtx.ArcOnS2()->Value(thevtx.ParameterOnArc2()); |
739 | u = p2d.X(); v = p2d.Y(); |
740 | p2d = thevtxbis.ArcOnS2()->Value(thevtxbis.ParameterOnArc2()); |
741 | if (Abs(u-p2d.X()) > Tol || Abs(v-p2d.Y()) > Tol) |
742 | { |
743 | changevtx = Standard_True; |
744 | break; |
745 | } |
746 | } |
747 | } |
748 | } |
749 | } |
750 | } |
751 | if (changevtx) { |
752 | thevtx.SetParameter(prm + 2.*PI); |
753 | glin->Replace(i,thevtx); |
754 | } |
755 | } |
756 | } |