Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1995-02-07 |
2 | // Created by: Jacques GOUSSARD | |
3 | // Copyright (c) 1995-1999 Matra Datavision | |
973c2be1 | 4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e | 5 | // |
973c2be1 | 6 | // This file is part of Open CASCADE Technology software library. |
b311480e | 7 | // |
d5f74e42 | 8 | // This library is free software; you can redistribute it and/or modify it under |
9 | // the terms of the GNU Lesser General Public License version 2.1 as published | |
973c2be1 | 10 | // by the Free Software Foundation, with special exception defined in the file |
11 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT | |
12 | // distribution for complete text of the license and disclaimer of any warranty. | |
b311480e | 13 | // |
973c2be1 | 14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. | |
7fd59977 | 16 | |
17 | #include <IntTools_LineConstructor.ixx> | |
18 | ||
19 | #include <GeomInt_LineTool.hxx> | |
20 | #include <GeomInt_SequenceOfParameterAndOrientation.hxx> | |
21 | #include <GeomInt_ParameterAndOrientation.hxx> | |
22 | ||
23 | #include <IntPatch_Point.hxx> | |
24 | #include <IntPatch_GLine.hxx> | |
25 | #include <IntPatch_WLine.hxx> | |
26 | #include <IntPatch_ALine.hxx> | |
27 | #include <IntSurf_Transition.hxx> | |
28 | #include <TopAbs_Orientation.hxx> | |
29 | ||
30 | ||
31 | #include <Precision.hxx> | |
32 | ||
33 | #include <gp_Pnt2d.hxx> | |
34 | ||
35 | #include <Adaptor2d_HCurve2d.hxx> | |
36 | ||
37 | #include <GeomAdaptor_HSurface.hxx> | |
38 | #include <Standard_ConstructionError.hxx> | |
39 | #include <IntSurf_Quadric.hxx> | |
40 | #include <IntSurf_PntOn2S.hxx> | |
41 | #include <ElCLib.hxx> | |
42 | #include <GeomAbs_SurfaceType.hxx> | |
7fd59977 | 43 | #include <TColStd_IndexedMapOfInteger.hxx> |
44 | ||
3928aec6 P |
45 | static |
46 | void Parameters(const Handle(GeomAdaptor_HSurface)& myHS1, | |
47 | const gp_Pnt& Ptref, | |
48 | Standard_Real& U1, | |
49 | Standard_Real& V1); | |
50 | static | |
51 | void Parameters(const Handle(GeomAdaptor_HSurface)& myHS1, | |
52 | const Handle(GeomAdaptor_HSurface)& myHS2, | |
53 | const gp_Pnt& Ptref, | |
54 | Standard_Real& U1, | |
55 | Standard_Real& V1, | |
56 | Standard_Real& U2, | |
57 | Standard_Real& V2); | |
58 | ||
59 | static | |
60 | void GLinePoint(const IntPatch_IType typl, | |
61 | const Handle(IntPatch_GLine)& GLine, | |
62 | const Standard_Real aT, | |
63 | gp_Pnt& aP); | |
64 | static | |
65 | void Recadre(const Handle(GeomAdaptor_HSurface)& myHS1, | |
66 | const Handle(GeomAdaptor_HSurface)& myHS2, | |
67 | Standard_Real& u1, | |
68 | Standard_Real& v1, | |
69 | Standard_Real& u2, | |
70 | Standard_Real& v2); | |
7fd59977 | 71 | |
72 | //======================================================================= | |
73 | //function : Perform | |
74 | //purpose : | |
75 | //======================================================================= | |
76 | void IntTools_LineConstructor::Perform(const Handle(IntPatch_Line)& L) | |
77 | { | |
78 | Standard_Integer i,nbvtx; | |
79 | Standard_Real firstp,lastp; | |
80 | const Standard_Real Tol = Precision::PConfusion() * 35.0; | |
81 | ||
82 | const IntPatch_IType typl = L->ArcType(); | |
3928aec6 | 83 | if(typl == IntPatch_Analytic) { |
7fd59977 | 84 | Standard_Real u1,v1,u2,v2; |
85 | Handle(IntPatch_ALine)& ALine = *((Handle(IntPatch_ALine) *)&L); | |
86 | seqp.Clear(); | |
87 | nbvtx = GeomInt_LineTool::NbVertex(L); | |
3928aec6 | 88 | for(i=1;i<nbvtx;i++) { |
7fd59977 | 89 | firstp = GeomInt_LineTool::Vertex(L,i).ParameterOnLine(); |
90 | lastp = GeomInt_LineTool::Vertex(L,i+1).ParameterOnLine(); | |
3928aec6 | 91 | if(firstp!=lastp) { |
7fd59977 | 92 | const Standard_Real pmid = (firstp+lastp)*0.5; |
93 | const gp_Pnt Pmid = ALine->Value(pmid); | |
94 | Parameters(myHS1,myHS2,Pmid,u1,v1,u2,v2); | |
95 | Recadre(myHS1,myHS2,u1,v1,u2,v2); | |
96 | const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol); | |
97 | if(in1 != TopAbs_OUT) { | |
98 | const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol); | |
99 | if(in2 != TopAbs_OUT) { | |
100 | seqp.Append(firstp); | |
101 | seqp.Append(lastp); | |
102 | } | |
103 | } | |
104 | } | |
105 | } | |
106 | done = Standard_True; | |
107 | return; | |
3928aec6 P |
108 | } // if(typl == IntPatch_Analytic) { |
109 | else if(typl == IntPatch_Walking) { | |
7fd59977 | 110 | Standard_Real u1,v1,u2,v2; |
111 | Handle(IntPatch_WLine)& WLine = *((Handle(IntPatch_WLine) *)&L); | |
112 | seqp.Clear(); | |
113 | nbvtx = GeomInt_LineTool::NbVertex(L); | |
3928aec6 | 114 | for(i=1;i<nbvtx;i++) { |
7fd59977 | 115 | firstp = GeomInt_LineTool::Vertex(L,i).ParameterOnLine(); |
116 | lastp = GeomInt_LineTool::Vertex(L,i+1).ParameterOnLine(); | |
3928aec6 P |
117 | if(firstp!=lastp) { |
118 | if(lastp != firstp+1) { | |
7fd59977 | 119 | const Standard_Integer pmid = (Standard_Integer )( (firstp+lastp)/2); |
120 | const IntSurf_PntOn2S& Pmid = WLine->Point(pmid); | |
121 | Pmid.Parameters(u1,v1,u2,v2); | |
122 | Recadre(myHS1,myHS2,u1,v1,u2,v2); | |
123 | const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol); | |
81bba717 | 124 | if(in1 != TopAbs_OUT) { |
7fd59977 | 125 | const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol); |
81bba717 | 126 | if(in2 != TopAbs_OUT) { |
7fd59977 | 127 | seqp.Append(firstp); |
128 | seqp.Append(lastp); | |
129 | } | |
130 | } | |
131 | } | |
3928aec6 | 132 | else { |
7fd59977 | 133 | const IntSurf_PntOn2S& Pfirst = WLine->Point((Standard_Integer)(firstp)); |
134 | Pfirst.Parameters(u1,v1,u2,v2); | |
135 | Recadre(myHS1,myHS2,u1,v1,u2,v2); | |
136 | TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol); | |
137 | if(in1 != TopAbs_OUT) { //-- !=ON donne Pb | |
138 | TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol); | |
139 | if(in2 != TopAbs_OUT) { //-- !=ON | |
140 | const IntSurf_PntOn2S& Plast = WLine->Point((Standard_Integer)(lastp)); | |
141 | Plast.Parameters(u1,v1,u2,v2); | |
142 | Recadre(myHS1,myHS2,u1,v1,u2,v2); | |
143 | in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol); | |
144 | if(in1 != TopAbs_OUT) { //-- !=ON donne Pb | |
145 | in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol); | |
146 | if(in2 != TopAbs_OUT) { | |
147 | seqp.Append(firstp); | |
148 | seqp.Append(lastp); | |
149 | } | |
150 | } | |
151 | } | |
152 | } | |
7fd59977 | 153 | } |
154 | } | |
155 | } | |
7fd59977 | 156 | // |
3928aec6 | 157 | // The One resulting curve consists of 7 segments that are |
7fd59977 | 158 | // connected between each other. |
3928aec6 | 159 | // The aim of the block is to reject these segments and have |
7fd59977 | 160 | // one segment instead of 7. |
161 | // The other reason to do that is value of TolReached3D=49. | |
162 | // Why -? It is not known yet. | |
163 | // PKV 22.Apr.2002 | |
164 | // | |
3928aec6 P |
165 | Standard_Integer aNbParts; |
166 | // | |
167 | aNbParts = seqp.Length()/2; | |
168 | if (aNbParts > 1) { | |
169 | Standard_Boolean bCond; | |
170 | GeomAbs_SurfaceType aST1, aST2; | |
171 | aST1 = myHS1->Surface().GetType(); | |
172 | aST2 = myHS2->Surface().GetType(); | |
173 | // | |
174 | bCond=Standard_False; | |
175 | if (aST1==GeomAbs_Plane) { | |
176 | if (aST2==GeomAbs_SurfaceOfExtrusion || | |
177 | aST2==GeomAbs_SurfaceOfRevolution) {//+zft | |
178 | bCond=!bCond; | |
7fd59977 | 179 | } |
3928aec6 P |
180 | } |
181 | else if (aST2==GeomAbs_Plane) { | |
182 | if (aST1==GeomAbs_SurfaceOfExtrusion || | |
183 | aST1==GeomAbs_SurfaceOfRevolution) {//+zft | |
184 | bCond=!bCond; | |
7fd59977 | 185 | } |
186 | } | |
187 | // | |
3928aec6 P |
188 | if (bCond) { |
189 | Standard_Integer aNb, anIndex, aNbTmp, jx; | |
190 | TColStd_IndexedMapOfInteger aMap; | |
191 | TColStd_SequenceOfReal aSeqTmp; | |
192 | // | |
193 | aNb=seqp.Length(); | |
194 | for(i=1; i<=aNb; ++i) { | |
195 | lastp =seqp(i); | |
196 | anIndex=(Standard_Integer)lastp; | |
197 | if (!aMap.Contains(anIndex)){ | |
198 | aMap.Add(anIndex); | |
199 | aSeqTmp.Append(lastp); | |
200 | } | |
201 | else { | |
202 | aNbTmp=aSeqTmp.Length(); | |
203 | aSeqTmp.Remove(aNbTmp); | |
204 | } | |
205 | } | |
206 | // | |
207 | seqp.Clear(); | |
208 | // | |
209 | aNb=aSeqTmp.Length()/2; | |
210 | for(i=1; i<=aNb;++i) { | |
211 | jx=2*i; | |
212 | firstp=aSeqTmp(jx-1); | |
213 | lastp =aSeqTmp(jx); | |
214 | seqp.Append(firstp); | |
215 | seqp.Append(lastp); | |
216 | } | |
217 | }//if (bCond) { | |
7fd59977 | 218 | } |
7fd59977 | 219 | done = Standard_True; |
220 | return; | |
3928aec6 P |
221 | }// else if(typl == IntPatch_Walking) { |
222 | // | |
fa0291ff | 223 | //----------------------------------------------------------- |
3928aec6 | 224 | else if (typl != IntPatch_Restriction) { |
7fd59977 | 225 | seqp.Clear(); |
3928aec6 P |
226 | // |
227 | Handle(IntPatch_GLine)& GLine = *((Handle(IntPatch_GLine) *)&L); | |
fa0291ff | 228 | // |
229 | if(typl == IntPatch_Circle || typl == IntPatch_Ellipse) { | |
230 | TreatCircle(L, Tol); | |
231 | done=Standard_True; | |
232 | return; | |
3928aec6 | 233 | } |
fa0291ff | 234 | //---------------------------- |
235 | Standard_Boolean intrvtested; | |
236 | Standard_Real u1,v1,u2,v2; | |
3928aec6 | 237 | // |
7fd59977 | 238 | nbvtx = GeomInt_LineTool::NbVertex(L); |
3928aec6 P |
239 | intrvtested = Standard_False; |
240 | for(i=1; i<nbvtx; ++i) { | |
7fd59977 | 241 | firstp = GeomInt_LineTool::Vertex(L,i).ParameterOnLine(); |
242 | lastp = GeomInt_LineTool::Vertex(L,i+1).ParameterOnLine(); | |
3928aec6 | 243 | if(Abs(firstp-lastp)>Precision::PConfusion()) { |
7fd59977 | 244 | intrvtested = Standard_True; |
245 | const Standard_Real pmid = (firstp+lastp)*0.5; | |
246 | gp_Pnt Pmid; | |
3928aec6 | 247 | GLinePoint(typl, GLine, pmid, Pmid); |
3928aec6 | 248 | // |
7fd59977 | 249 | Parameters(myHS1,myHS2,Pmid,u1,v1,u2,v2); |
250 | Recadre(myHS1,myHS2,u1,v1,u2,v2); | |
251 | const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol); | |
252 | if(in1 != TopAbs_OUT) { | |
253 | const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol); | |
254 | if(in2 != TopAbs_OUT) { | |
255 | seqp.Append(firstp); | |
256 | seqp.Append(lastp); | |
257 | } | |
258 | } | |
259 | } | |
260 | } | |
3928aec6 | 261 | // |
7fd59977 | 262 | if (!intrvtested) { |
81bba717 | 263 | // Keep a priori. A point 2d on each |
264 | // surface is required to make the decision. Will be done in the caller | |
7fd59977 | 265 | seqp.Append(GeomInt_LineTool::FirstParameter(L)); |
266 | seqp.Append(GeomInt_LineTool::LastParameter(L)); | |
267 | } | |
268 | // | |
7fd59977 | 269 | done =Standard_True; |
270 | return; | |
fa0291ff | 271 | } // else if (typl != IntPatch_Restriction) { |
7fd59977 | 272 | |
273 | done = Standard_False; | |
274 | seqp.Clear(); | |
275 | nbvtx = GeomInt_LineTool::NbVertex(L); | |
81bba717 | 276 | if (nbvtx == 0) { // Keep a priori. Point 2d is required on each |
277 | // surface to make the decision. Will be done in the caller | |
7fd59977 | 278 | seqp.Append(GeomInt_LineTool::FirstParameter(L)); |
279 | seqp.Append(GeomInt_LineTool::LastParameter(L)); | |
280 | done = Standard_True; | |
281 | return; | |
282 | } | |
283 | ||
284 | GeomInt_SequenceOfParameterAndOrientation seqpss; | |
285 | TopAbs_Orientation or1=TopAbs_FORWARD,or2=TopAbs_FORWARD; | |
286 | ||
3928aec6 | 287 | for (i=1; i<=nbvtx; i++) { |
7fd59977 | 288 | const IntPatch_Point& thevtx = GeomInt_LineTool::Vertex(L,i); |
289 | const Standard_Real prm = thevtx.ParameterOnLine(); | |
3928aec6 P |
290 | if (thevtx.IsOnDomS1()) { |
291 | switch (thevtx.TransitionLineArc1().TransitionType()) { | |
7fd59977 | 292 | case IntSurf_In: or1 = TopAbs_FORWARD; break; |
293 | case IntSurf_Out: or1 = TopAbs_REVERSED; break; | |
294 | case IntSurf_Touch: or1 = TopAbs_INTERNAL; break; | |
295 | case IntSurf_Undecided: or1 = TopAbs_INTERNAL; break; | |
296 | } | |
297 | } | |
3928aec6 | 298 | else { |
7fd59977 | 299 | or1 = TopAbs_INTERNAL; |
3928aec6 | 300 | } |
7fd59977 | 301 | |
3928aec6 P |
302 | if (thevtx.IsOnDomS2()) { |
303 | switch (thevtx.TransitionLineArc2().TransitionType()) { | |
7fd59977 | 304 | case IntSurf_In: or2 = TopAbs_FORWARD; break; |
305 | case IntSurf_Out: or2 = TopAbs_REVERSED; break; | |
306 | case IntSurf_Touch: or2 = TopAbs_INTERNAL; break; | |
307 | case IntSurf_Undecided: or2 = TopAbs_INTERNAL; break; | |
308 | } | |
309 | } | |
3928aec6 | 310 | else { |
7fd59977 | 311 | or2 = TopAbs_INTERNAL; |
3928aec6 P |
312 | } |
313 | // | |
7fd59977 | 314 | const Standard_Integer nbinserted = seqpss.Length(); |
315 | Standard_Boolean inserted = Standard_False; | |
3928aec6 P |
316 | for (Standard_Integer j=1; j<=nbinserted;j++) { |
317 | if (Abs(prm-seqpss(j).Parameter()) <= Tol) { | |
81bba717 | 318 | // accumulate |
7fd59977 | 319 | GeomInt_ParameterAndOrientation& valj = seqpss.ChangeValue(j); |
320 | if (or1 != TopAbs_INTERNAL) { | |
321 | if (valj.Orientation1() != TopAbs_INTERNAL) { | |
322 | if (or1 != valj.Orientation1()) { | |
323 | valj.SetOrientation1(TopAbs_INTERNAL); | |
324 | } | |
325 | } | |
326 | else { | |
327 | valj.SetOrientation1(or1); | |
328 | } | |
329 | } | |
330 | ||
331 | if (or2 != TopAbs_INTERNAL) { | |
332 | if (valj.Orientation2() != TopAbs_INTERNAL) { | |
333 | if (or2 != valj.Orientation2()) { | |
334 | valj.SetOrientation2(TopAbs_INTERNAL); | |
335 | } | |
336 | } | |
337 | else { | |
338 | valj.SetOrientation2(or2); | |
339 | } | |
340 | } | |
341 | inserted = Standard_True; | |
342 | break; | |
343 | } | |
344 | ||
345 | if (prm < seqpss(j).Parameter()-Tol ) { | |
81bba717 | 346 | // insert before position j |
7fd59977 | 347 | seqpss.InsertBefore(j,GeomInt_ParameterAndOrientation(prm,or1,or2)); |
348 | inserted = Standard_True; | |
349 | break; | |
350 | } | |
351 | ||
352 | } | |
353 | if (!inserted) { | |
354 | seqpss.Append(GeomInt_ParameterAndOrientation(prm,or1,or2)); | |
355 | } | |
356 | } | |
357 | ||
81bba717 | 358 | // determine the state at the beginning of line |
7fd59977 | 359 | Standard_Boolean trim = Standard_False; |
360 | Standard_Boolean dansS1 = Standard_False; | |
361 | Standard_Boolean dansS2 = Standard_False; | |
362 | ||
363 | nbvtx = seqpss.Length(); | |
3928aec6 | 364 | for (i=1; i<= nbvtx; i++) { |
7fd59977 | 365 | or1 = seqpss(i).Orientation1(); |
3928aec6 | 366 | if (or1 != TopAbs_INTERNAL) { |
7fd59977 | 367 | trim = Standard_True; |
368 | dansS1 = (or1 != TopAbs_FORWARD); | |
369 | break; | |
370 | } | |
371 | } | |
372 | ||
3928aec6 | 373 | if (i > nbvtx) { |
7fd59977 | 374 | Standard_Real U,V; |
3928aec6 P |
375 | for (i=1; i<=GeomInt_LineTool::NbVertex(L); i++ ) { |
376 | if (!GeomInt_LineTool::Vertex(L,i).IsOnDomS1() ) { | |
7fd59977 | 377 | GeomInt_LineTool::Vertex(L,i).ParametersOnS1(U,V); |
378 | gp_Pnt2d PPCC(U,V); | |
379 | if (myDom1->Classify(PPCC,Tol) == TopAbs_OUT) { | |
380 | done = Standard_True; | |
381 | return; | |
382 | } | |
383 | break; | |
384 | } | |
385 | } | |
81bba717 | 386 | dansS1 = Standard_True; // Keep in doubt |
7fd59977 | 387 | } |
3928aec6 P |
388 | // |
389 | for (i=1; i<= nbvtx; i++) { | |
7fd59977 | 390 | or2 = seqpss(i).Orientation2(); |
3928aec6 | 391 | if (or2 != TopAbs_INTERNAL) { |
7fd59977 | 392 | trim = Standard_True; |
393 | dansS2 = (or2 != TopAbs_FORWARD); | |
394 | break; | |
395 | } | |
396 | } | |
397 | ||
3928aec6 | 398 | if (i > nbvtx) { |
7fd59977 | 399 | Standard_Real U,V; |
3928aec6 P |
400 | for (i=1; i<=GeomInt_LineTool::NbVertex(L); i++ ) { |
401 | if (!GeomInt_LineTool::Vertex(L,i).IsOnDomS2() ) { | |
7fd59977 | 402 | GeomInt_LineTool::Vertex(L,i).ParametersOnS2(U,V); |
403 | if (myDom2->Classify(gp_Pnt2d(U,V),Tol) == TopAbs_OUT) { | |
404 | done = Standard_True; | |
405 | return; | |
406 | } | |
407 | break; | |
408 | } | |
409 | } | |
81bba717 | 410 | dansS2 = Standard_True; // Keep in doubt |
7fd59977 | 411 | } |
412 | ||
81bba717 | 413 | if (!trim) { // necessarily dansS1 == dansS2 == Standard_True |
7fd59977 | 414 | seqp.Append(GeomInt_LineTool::FirstParameter(L)); |
415 | seqp.Append(GeomInt_LineTool::LastParameter(L)); | |
416 | done = Standard_True; | |
417 | return; | |
418 | } | |
419 | ||
81bba717 | 420 | // sequence seqpss is peeled to create valid ends |
421 | // and store them in seqp(2*i+1) and seqp(2*i+2) | |
7fd59977 | 422 | Standard_Real thefirst = GeomInt_LineTool::FirstParameter(L); |
423 | Standard_Real thelast = GeomInt_LineTool::LastParameter(L); | |
424 | firstp = thefirst; | |
425 | ||
3928aec6 | 426 | for (i=1; i<=nbvtx; i++) { |
7fd59977 | 427 | or1 = seqpss(i).Orientation1(); |
428 | or2 = seqpss(i).Orientation2(); | |
3928aec6 P |
429 | if (dansS1 && dansS2) { |
430 | if (or1 == TopAbs_REVERSED){ | |
7fd59977 | 431 | dansS1 = Standard_False; |
3928aec6 P |
432 | } |
433 | ||
434 | if (or2 == TopAbs_REVERSED){ | |
7fd59977 | 435 | dansS2 = Standard_False; |
3928aec6 P |
436 | } |
437 | if (!dansS1 || !dansS2) { | |
7fd59977 | 438 | lastp = seqpss(i).Parameter(); |
439 | Standard_Real stofirst = Max(firstp, thefirst); | |
440 | Standard_Real stolast = Min(lastp, thelast) ; | |
441 | ||
442 | if (stolast > stofirst) { | |
443 | seqp.Append(stofirst); | |
444 | seqp.Append(stolast); | |
445 | } | |
3928aec6 | 446 | if (lastp > thelast) { |
7fd59977 | 447 | break; |
3928aec6 | 448 | } |
7fd59977 | 449 | } |
450 | } | |
3928aec6 P |
451 | else { |
452 | if (dansS1) { | |
453 | if (or1 == TopAbs_REVERSED) { | |
7fd59977 | 454 | dansS1 = Standard_False; |
3928aec6 | 455 | } |
7fd59977 | 456 | } |
3928aec6 P |
457 | else { |
458 | if (or1 == TopAbs_FORWARD){ | |
7fd59977 | 459 | dansS1 = Standard_True; |
3928aec6 | 460 | } |
7fd59977 | 461 | } |
3928aec6 P |
462 | if (dansS2) { |
463 | if (or2 == TopAbs_REVERSED) { | |
7fd59977 | 464 | dansS2 = Standard_False; |
3928aec6 | 465 | } |
7fd59977 | 466 | } |
3928aec6 P |
467 | else { |
468 | if (or2 == TopAbs_FORWARD){ | |
7fd59977 | 469 | dansS2 = Standard_True; |
3928aec6 | 470 | } |
7fd59977 | 471 | } |
3928aec6 | 472 | if (dansS1 && dansS2){ |
7fd59977 | 473 | firstp = seqpss(i).Parameter(); |
3928aec6 | 474 | } |
7fd59977 | 475 | } |
476 | } | |
3928aec6 | 477 | // |
81bba717 | 478 | // finally to add |
3928aec6 | 479 | if (dansS1 && dansS2) { |
7fd59977 | 480 | lastp = thelast; |
481 | firstp = Max(firstp,thefirst); | |
482 | if (lastp > firstp) { | |
483 | seqp.Append(firstp); | |
484 | seqp.Append(lastp); | |
485 | } | |
486 | } | |
487 | done = Standard_True; | |
488 | } | |
3928aec6 P |
489 | //======================================================================= |
490 | //function : Recadre | |
491 | //purpose : | |
492 | //======================================================================= | |
493 | void Recadre(const Handle(GeomAdaptor_HSurface)& myHS1, | |
494 | const Handle(GeomAdaptor_HSurface)& myHS2, | |
495 | Standard_Real& u1, | |
496 | Standard_Real& v1, | |
497 | Standard_Real& u2, | |
498 | Standard_Real& v2) | |
499 | { | |
500 | Standard_Boolean myHS1IsUPeriodic,myHS1IsVPeriodic; | |
501 | const GeomAbs_SurfaceType typs1 = myHS1->GetType(); | |
502 | switch (typs1) | |
503 | { | |
504 | case GeomAbs_Cylinder: | |
505 | case GeomAbs_Cone: | |
506 | case GeomAbs_Sphere: | |
507 | { | |
508 | myHS1IsUPeriodic = Standard_True; | |
509 | myHS1IsVPeriodic = Standard_False; | |
510 | break; | |
511 | } | |
512 | case GeomAbs_Torus: | |
513 | { | |
514 | myHS1IsUPeriodic = myHS1IsVPeriodic = Standard_True; | |
515 | break; | |
516 | } | |
517 | default: | |
518 | { | |
519 | //-- Case of periodic biparameters is processed upstream | |
520 | myHS1IsUPeriodic = myHS1IsVPeriodic = Standard_False; | |
521 | break; | |
522 | } | |
523 | } | |
524 | Standard_Boolean myHS2IsUPeriodic,myHS2IsVPeriodic; | |
525 | const GeomAbs_SurfaceType typs2 = myHS2->GetType(); | |
526 | switch (typs2) | |
527 | { | |
528 | case GeomAbs_Cylinder: | |
529 | case GeomAbs_Cone: | |
530 | case GeomAbs_Sphere: | |
531 | { | |
532 | myHS2IsUPeriodic = Standard_True; | |
533 | myHS2IsVPeriodic = Standard_False; | |
534 | break; | |
535 | } | |
536 | case GeomAbs_Torus: | |
537 | { | |
538 | myHS2IsUPeriodic = myHS2IsVPeriodic = Standard_True; | |
539 | break; | |
540 | } | |
541 | default: | |
542 | { | |
543 | //-- Case of periodic biparameters is processed upstream | |
544 | myHS2IsUPeriodic = myHS2IsVPeriodic = Standard_False; | |
545 | break; | |
546 | } | |
547 | } | |
548 | if(myHS1IsUPeriodic) { | |
a33798d8 | 549 | const Standard_Real lmf = M_PI+M_PI; //-- myHS1->UPeriod(); |
3928aec6 P |
550 | const Standard_Real f = myHS1->FirstUParameter(); |
551 | const Standard_Real l = myHS1->LastUParameter(); | |
552 | while(u1 < f) { u1+=lmf; } | |
553 | while(u1 > l) { u1-=lmf; } | |
554 | } | |
555 | if(myHS1IsVPeriodic) { | |
a33798d8 | 556 | const Standard_Real lmf = M_PI+M_PI; //-- myHS1->VPeriod(); |
3928aec6 P |
557 | const Standard_Real f = myHS1->FirstVParameter(); |
558 | const Standard_Real l = myHS1->LastVParameter(); | |
559 | while(v1 < f) { v1+=lmf; } | |
560 | while(v1 > l) { v1-=lmf; } | |
561 | } | |
562 | if(myHS2IsUPeriodic) { | |
a33798d8 | 563 | const Standard_Real lmf = M_PI+M_PI; //-- myHS2->UPeriod(); |
3928aec6 P |
564 | const Standard_Real f = myHS2->FirstUParameter(); |
565 | const Standard_Real l = myHS2->LastUParameter(); | |
566 | while(u2 < f) { u2+=lmf; } | |
567 | while(u2 > l) { u2-=lmf; } | |
568 | } | |
569 | if(myHS2IsVPeriodic) { | |
a33798d8 | 570 | const Standard_Real lmf = M_PI+M_PI; //-- myHS2->VPeriod(); |
3928aec6 P |
571 | const Standard_Real f = myHS2->FirstVParameter(); |
572 | const Standard_Real l = myHS2->LastVParameter(); | |
573 | while(v2 < f) { v2+=lmf; } | |
574 | while(v2 > l) { v2-=lmf; } | |
575 | } | |
576 | } | |
577 | //======================================================================= | |
578 | //function : Parameters | |
579 | //purpose : | |
580 | //======================================================================= | |
581 | void Parameters(const Handle(GeomAdaptor_HSurface)& myHS1, | |
582 | const Handle(GeomAdaptor_HSurface)& myHS2, | |
583 | const gp_Pnt& Ptref, | |
584 | Standard_Real& U1, | |
585 | Standard_Real& V1, | |
586 | Standard_Real& U2, | |
587 | Standard_Real& V2) | |
588 | { | |
3928aec6 P |
589 | Parameters(myHS1, Ptref, U1, V1); |
590 | Parameters(myHS2, Ptref, U2, V2); | |
3928aec6 | 591 | } |
3928aec6 P |
592 | //======================================================================= |
593 | //function : Parameter | |
594 | //purpose : | |
595 | //======================================================================= | |
596 | void Parameters(const Handle(GeomAdaptor_HSurface)& myHS1, | |
7eed5d29 | 597 | const gp_Pnt& Ptref, |
598 | Standard_Real& U1, | |
599 | Standard_Real& V1) | |
3928aec6 P |
600 | { |
601 | IntSurf_Quadric quad1; | |
602 | // | |
603 | switch (myHS1->Surface().GetType()) { | |
604 | case GeomAbs_Plane: | |
605 | quad1.SetValue(myHS1->Surface().Plane()); | |
606 | break; | |
607 | case GeomAbs_Cylinder: | |
608 | quad1.SetValue(myHS1->Surface().Cylinder()); | |
609 | break; | |
610 | case GeomAbs_Cone: | |
611 | quad1.SetValue(myHS1->Surface().Cone()); | |
612 | break; | |
613 | case GeomAbs_Sphere: | |
614 | quad1.SetValue(myHS1->Surface().Sphere()); | |
615 | break; | |
7eed5d29 | 616 | case GeomAbs_Torus: |
617 | quad1.SetValue(myHS1->Surface().Torus()); | |
618 | break; | |
3928aec6 P |
619 | default: |
620 | Standard_ConstructionError::Raise("IntTools_LineConstructor::Parameters"); | |
621 | } | |
622 | quad1.Parameters(Ptref,U1,V1); | |
623 | } | |
624 | ||
625 | //======================================================================= | |
626 | //function : GLinePoint | |
627 | //purpose : | |
628 | //======================================================================= | |
629 | void GLinePoint(const IntPatch_IType typl, | |
630 | const Handle(IntPatch_GLine)& GLine, | |
631 | const Standard_Real aT, | |
632 | gp_Pnt& aP) | |
633 | { | |
634 | switch (typl) { | |
635 | case IntPatch_Lin: | |
636 | aP = ElCLib::Value(aT, GLine->Line()); | |
637 | break; | |
638 | case IntPatch_Circle: | |
639 | aP = ElCLib::Value(aT, GLine->Circle()); | |
640 | break; | |
641 | case IntPatch_Ellipse: | |
642 | aP = ElCLib::Value(aT, GLine->Ellipse()); | |
643 | break; | |
644 | case IntPatch_Hyperbola: | |
645 | aP = ElCLib::Value(aT, GLine->Hyperbola()); | |
646 | break; | |
647 | case IntPatch_Parabola: | |
648 | aP = ElCLib::Value(aT, GLine->Parabola()); | |
649 | break; | |
650 | default: | |
651 | Standard_ConstructionError::Raise("IntTools_LineConstructor::Parameters"); | |
652 | } | |
653 | } | |
fa0291ff | 654 | |
655 | //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | |
656 | // | |
657 | //======================================================================= | |
658 | //class : IntTools_RealWithFlag | |
659 | //purpose : | |
660 | //======================================================================= | |
661 | class IntTools_RealWithFlag { | |
662 | public: | |
663 | IntTools_RealWithFlag() : | |
664 | myValue(-99.), myFlag(1) | |
665 | { | |
666 | }; | |
667 | // | |
668 | ~IntTools_RealWithFlag() { | |
669 | }; | |
670 | // | |
671 | void SetValue(const Standard_Real aT) { | |
672 | myValue=aT; | |
673 | }; | |
674 | // | |
675 | Standard_Real Value() const { | |
676 | return myValue; | |
677 | } | |
678 | // | |
679 | void SetFlag(const Standard_Integer aFlag) { | |
680 | myFlag=aFlag; | |
681 | }; | |
682 | // | |
683 | Standard_Integer Flag() const { | |
684 | return myFlag; | |
685 | } | |
686 | // | |
687 | Standard_Boolean operator < (const IntTools_RealWithFlag& aOther) { | |
688 | return myValue<aOther.myValue; | |
689 | } | |
690 | // | |
691 | protected: | |
692 | Standard_Real myValue; | |
693 | Standard_Integer myFlag; | |
694 | }; | |
695 | //------------ | |
696 | static | |
697 | void SortShell(const Standard_Integer, | |
698 | IntTools_RealWithFlag *); | |
699 | static | |
700 | void RejectDuplicates(Standard_Integer& aNbVtx, | |
701 | IntTools_RealWithFlag *pVtx, | |
702 | Standard_Real aTolPrm); | |
703 | static | |
704 | void RejectNearBeacons(Standard_Integer& aNbVtx, | |
705 | IntTools_RealWithFlag *pVtx, | |
706 | Standard_Real aTolPC1, | |
707 | const GeomAbs_SurfaceType aTS1, | |
708 | const GeomAbs_SurfaceType aTS2); | |
709 | static | |
710 | Standard_Real AdjustOnPeriod(const Standard_Real aTr, | |
711 | const Standard_Real aPeriod); | |
712 | ||
713 | static | |
714 | Standard_Boolean RejectMicroCircle(const Handle(IntPatch_GLine)& aGLine, | |
715 | const IntPatch_IType aType, | |
716 | const Standard_Real aTol3D); | |
717 | // | |
718 | //======================================================================= | |
719 | //function : TreatCircle | |
720 | //purpose : | |
721 | //======================================================================= | |
722 | void IntTools_LineConstructor::TreatCircle(const Handle(IntPatch_Line)& aLine, | |
723 | const Standard_Real aTol) | |
724 | { | |
725 | Standard_Boolean bRejected; | |
726 | IntPatch_IType aType; | |
727 | // | |
728 | aType=aLine->ArcType(); | |
729 | Handle(IntPatch_GLine)& aGLine=*((Handle(IntPatch_GLine) *)&aLine); | |
730 | // | |
731 | bRejected=RejectMicroCircle(aGLine, aType, aTol); | |
732 | if (bRejected) { | |
733 | return; | |
734 | } | |
735 | //---------------------------------------- | |
729d84d4 | 736 | Standard_Boolean bFound; |
fa0291ff | 737 | Standard_Integer aNbVtx, aNbVtxWas, i; |
738 | Standard_Real aTolPC, aT, aT1, aT2, aTmid, aTwoPI, aTolPC1; | |
739 | Standard_Real aU1, aV1, aU2, aV2; | |
740 | TopAbs_State aIn1, aIn2; | |
741 | GeomAbs_SurfaceType aTS1, aTS2; | |
742 | gp_Pnt aPmid; | |
743 | gp_Pnt2d aP2D; | |
744 | IntTools_RealWithFlag *pVtx; | |
745 | //-------------------------------------1 | |
746 | aTwoPI=M_PI+M_PI; | |
747 | aTolPC=Precision::PConfusion(); | |
748 | aNbVtxWas=GeomInt_LineTool::NbVertex(aLine); | |
729d84d4 | 749 | |
fa0291ff | 750 | aNbVtx=aNbVtxWas+2; |
751 | //-------------------------------------2 | |
752 | aTS1=myHS1->GetType(); | |
753 | aTS2=myHS2->GetType(); | |
754 | // | |
755 | // About the value aTolPC1=1000.*aTolPC, | |
756 | // see IntPatch_GLine.cxx, line:398 | |
757 | // for more details; | |
758 | aTolPC1=1000.*aTolPC; | |
759 | //------------------------------------- | |
760 | // | |
761 | pVtx=new IntTools_RealWithFlag [aNbVtx]; | |
762 | // | |
763 | pVtx[0].SetValue(0.); | |
729d84d4 | 764 | pVtx[1].SetValue(aTwoPI); |
fa0291ff | 765 | // |
766 | for(i=1; i<=aNbVtxWas; ++i) { | |
767 | aT=GeomInt_LineTool::Vertex(aLine, i).ParameterOnLine(); | |
768 | aT=AdjustOnPeriod(aT, aTwoPI); | |
769 | pVtx[i+1].SetValue(aT); | |
770 | } | |
771 | // | |
772 | SortShell(aNbVtx, pVtx); | |
773 | // | |
774 | RejectNearBeacons(aNbVtx, pVtx, aTolPC1, aTS1, aTS2); | |
775 | // | |
776 | RejectDuplicates(aNbVtx, pVtx, aTolPC); | |
777 | // | |
729d84d4 | 778 | if ((aType==IntPatch_Circle || aType==IntPatch_Ellipse)&& aNbVtx>2) { // zz |
779 | bFound=Standard_False; | |
780 | for(i=1; i<=aNbVtxWas; ++i) { | |
781 | aT=GeomInt_LineTool::Vertex(aLine, i).ParameterOnLine(); | |
782 | if (fabs(aT) < aTolPC1 || fabs(aT-aTwoPI) < aTolPC1) { | |
783 | bFound=!bFound; | |
784 | break; | |
785 | } | |
786 | } | |
787 | if (!bFound) { | |
788 | aT=pVtx[1].Value()+aTwoPI; | |
789 | pVtx[aNbVtx-1].SetValue(aT); | |
790 | // | |
791 | for(i=0; i<aNbVtx; ++i) { | |
792 | aT=pVtx[i+1].Value(); | |
793 | pVtx[i].SetValue(aT); | |
794 | } | |
795 | --aNbVtx; | |
796 | } | |
797 | } | |
798 | // | |
fa0291ff | 799 | for(i=0; i<aNbVtx-1; ++i) { |
800 | aT1=pVtx[i].Value(); | |
801 | aT2=pVtx[i+1].Value(); | |
802 | aTmid=(aT1+aT2)*0.5; | |
803 | GLinePoint(aType, aGLine, aTmid, aPmid); | |
804 | // | |
805 | Parameters(myHS1, myHS2, aPmid, aU1, aV1, aU2, aV2); | |
806 | Recadre(myHS1, myHS2, aU1, aV1, aU2, aV2); | |
807 | // | |
808 | aP2D.SetCoord(aU1, aV1); | |
809 | aIn1=myDom1->Classify(aP2D, aTol); | |
810 | if(aIn1 != TopAbs_OUT) { | |
811 | aP2D.SetCoord(aU2, aV2); | |
812 | aIn2=myDom2->Classify(aP2D, aTol); | |
813 | if(aIn2 != TopAbs_OUT) { | |
814 | seqp.Append(aT1); | |
815 | seqp.Append(aT2); | |
816 | } | |
817 | } | |
818 | } | |
819 | // | |
820 | delete [] pVtx; | |
821 | } | |
822 | //======================================================================= | |
823 | //function : RejectNearBeacons | |
824 | //purpose : Reject the thickenings near the beacon points (if exist) | |
825 | // The gifts, made by sweep algo. | |
826 | // chl/930/B5 B8 C2 C5 E2 E5 E8 F2 G8 H2 H5 H8 | |
827 | //======================================================================= | |
828 | void RejectNearBeacons(Standard_Integer& aNbVtx, | |
829 | IntTools_RealWithFlag *pVtx, | |
830 | Standard_Real aTolPC1, | |
831 | const GeomAbs_SurfaceType aTS1, | |
832 | const GeomAbs_SurfaceType aTS2) | |
833 | { | |
834 | Standard_Integer i, j, iBcn; | |
835 | Standard_Real aT, aBcn[2]; | |
836 | // | |
837 | if (aTS1==GeomAbs_Cylinder && aTS2==GeomAbs_Cylinder) { | |
838 | aBcn[0]=0.5*M_PI; | |
839 | aBcn[1]=1.5*M_PI; | |
840 | // | |
841 | for (j=0; j<2; ++j) { | |
842 | iBcn=-1; | |
843 | for(i=0; i<aNbVtx; ++i) { | |
844 | aT=pVtx[i].Value(); | |
845 | if (aT==aBcn[j]) { | |
846 | iBcn=i; | |
847 | break; | |
848 | } | |
849 | } | |
850 | // | |
851 | if (iBcn<0) { | |
852 | // The beacon is not found | |
853 | continue; | |
854 | } | |
855 | // | |
856 | for(i=0; i<aNbVtx; ++i) { | |
857 | if (i!=iBcn) { | |
858 | aT=pVtx[i].Value(); | |
859 | if (fabs(aT-aBcn[j]) < aTolPC1) { | |
860 | pVtx[i].SetFlag(0); | |
861 | } | |
862 | } | |
863 | } | |
864 | }// for (j=0; j<2; ++j) { | |
865 | //------------------------------------------ | |
866 | j=0; | |
867 | for(i=0; i<aNbVtx; ++i) { | |
868 | if (pVtx[i].Flag()) { | |
869 | pVtx[j]=pVtx[i]; | |
870 | ++j; | |
871 | } | |
872 | } | |
873 | aNbVtx=j; | |
874 | }// if (aTS1==GeomAbs_Cylinder && aTS2==GeomAbs_Cylinder) { | |
875 | } | |
876 | ||
877 | //======================================================================= | |
878 | //function : RejectDuplicates | |
879 | //purpose : | |
880 | //======================================================================= | |
881 | void RejectDuplicates(Standard_Integer& aNbVtx, | |
882 | IntTools_RealWithFlag *pVtx, | |
883 | Standard_Real aTolPC) | |
884 | { | |
885 | Standard_Integer i, j; | |
886 | Standard_Real dX, aT1, aT2; | |
887 | // | |
888 | for(i=0; i<aNbVtx-1; ++i) { | |
889 | aT2=pVtx[i+1].Value(); | |
890 | aT1=pVtx[i].Value(); | |
891 | dX=aT2-aT1; | |
892 | if (dX<aTolPC) { | |
893 | pVtx[i+1].SetFlag(0); | |
894 | } | |
895 | } | |
896 | // | |
897 | j=0; | |
898 | for(i=0; i<aNbVtx; ++i) { | |
899 | if (pVtx[i].Flag()) { | |
900 | pVtx[j]=pVtx[i]; | |
901 | ++j; | |
902 | } | |
903 | } | |
904 | aNbVtx=j; | |
905 | } | |
906 | //======================================================================= | |
907 | //function : AdjustOnPeriod | |
908 | //purpose : | |
909 | //======================================================================= | |
910 | Standard_Real AdjustOnPeriod(const Standard_Real aTr, | |
911 | const Standard_Real aPeriod) | |
912 | { | |
913 | Standard_Integer k; | |
914 | Standard_Real aT; | |
915 | // | |
916 | aT=aTr; | |
917 | if (aT<0.) { | |
918 | k=-(Standard_Integer)(aT/aPeriod)+1; | |
919 | aT=aT+k*aPeriod; | |
920 | } | |
921 | // | |
922 | if (!(aT>=0. && aT<=aPeriod)) { | |
923 | k=(Standard_Integer)(aT/aPeriod); | |
924 | aT=aT-k*aPeriod; | |
925 | } | |
926 | // | |
927 | return aT; | |
928 | } | |
929 | //======================================================================= | |
930 | //function : RejectMicroCrcles | |
931 | //purpose : | |
932 | //======================================================================= | |
933 | Standard_Boolean RejectMicroCircle(const Handle(IntPatch_GLine)& aGLine, | |
934 | const IntPatch_IType aType, | |
935 | const Standard_Real aTol3D) | |
936 | { | |
937 | Standard_Boolean bRet; | |
938 | Standard_Real aR; | |
939 | // | |
940 | bRet=Standard_False; | |
941 | // | |
942 | if (aType==IntPatch_Circle) { | |
943 | aR=aGLine->Circle().Radius(); | |
944 | bRet=(aR<aTol3D); | |
945 | } | |
946 | else if (aType==IntPatch_Ellipse) { | |
947 | aR=aGLine->Ellipse().MajorRadius(); | |
948 | bRet=(aR<aTol3D); | |
949 | } | |
950 | return bRet; | |
951 | } | |
952 | //======================================================================= | |
953 | // function: SortShell | |
954 | // purpose : | |
955 | //======================================================================= | |
956 | void SortShell(const Standard_Integer n, | |
957 | IntTools_RealWithFlag *a) | |
958 | { | |
959 | Standard_Integer nd, i, j, l, d=1; | |
960 | IntTools_RealWithFlag x; | |
961 | // | |
962 | while(d<=n) { | |
963 | d*=2; | |
964 | } | |
965 | // | |
966 | while (d) { | |
967 | d=(d-1)/2; | |
968 | // | |
969 | nd=n-d; | |
970 | for (i=0; i<nd; ++i) { | |
971 | j=i; | |
972 | m30:; | |
973 | l=j+d; | |
974 | if (a[l] < a[j]){ | |
975 | x=a[j]; | |
976 | a[j]=a[l]; | |
977 | a[l]=x; | |
978 | j-=d; | |
979 | if (j > -1) goto m30; | |
980 | }//if (a[l] < a[j]){ | |
981 | }//for (i=0; i<nd; ++i) | |
982 | }//while (1) | |
983 | } |