0023625: New functionality building reflect lines on a shape
[occt.git] / src / Contap / Contap_ContourGen_2.gxx
CommitLineData
b311480e 1// Created on: 1993-02-05
2// Created by: Jacques GOUSSARD
3// Copyright (c) 1993-1999 Matra Datavision
4// Copyright (c) 1999-2012 OPEN CASCADE SAS
5//
6// The content of this file is subject to the Open CASCADE Technology Public
7// License Version 6.5 (the "License"). You may not use the content of this file
8// except in compliance with the License. Please obtain a copy of the License
9// at http://www.opencascade.org and read it completely before using this file.
10//
11// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13//
14// The Original Code and all software distributed under the License is
15// distributed on an "AS IS" basis, without warranty of any kind, and the
16// Initial Developer hereby disclaims all such warranties, including without
17// limitation, any warranties of merchantability, fitness for a particular
18// purpose or non-infringement. Please see the License for the specific terms
19// and conditions governing the rights and limitations under the License.
20
7fd59977 21
22#include <math_Vector.hxx>
23#include <math_Matrix.hxx>
24#include <TopTrans_CurveTransition.hxx>
25#include <TopAbs_State.hxx>
26#include <TopAbs_Orientation.hxx>
27#include <TColStd_Array1OfInteger.hxx>
28#include <gp_Pnt2d.hxx>
29#include <gp.hxx>
30#include <IntSurf_InteriorPoint.hxx>
31
32#include <IntSurf_TypeTrans.hxx>
33
34#include <Precision.hxx>
35
36#include <BndLib_AddSurface.hxx>
37#include <Bnd_Box.hxx>
38
39
40#include <ElSLib.hxx>
41
42#define tole 5.e-6
43
44
45
46
47
48static IntSurf_TypeTrans ComputeTransitionOnLine
49 (Contap_TheSurfFunction&,
50 const Standard_Real,
51 const Standard_Real,
52 const gp_Vec&);
53
54
55static IntSurf_TypeTrans ComputeTransitionOngpCircle
56 (Contap_TheSurfFunction&,
57 const gp_Circ&);
58
59
60static IntSurf_TypeTrans ComputeTransitionOngpLine
61 (Contap_TheSurfFunction&,
62 const gp_Lin&);
63
64
65static void ComputeInternalPoints
66 (Contap_TheLine& Line,
67 Contap_TheSurfFunction&,
68 const Standard_Real ureso,
69 const Standard_Real vreso);
70
71
72static void ComputeInternalPointsOnRstr
73 (Contap_TheLine&,
74 const Standard_Real,
75 const Standard_Real,
76 Contap_TheSurfFunction&);
77
78static void ProcessSegments (const Contap_TheSearch&,
79 Contap_TheSequenceOfLine&,
80 const Standard_Real,
81 Contap_TheSurfFunction&,
82 const Handle(TheTopolTool)&);
83
84//-- --------------------------------------------------------------------------------
85//-- Recherche des portions utiles sur les lignes
86
87
88static void Recadre(const TheSurface& myHS1,
89 Standard_Real& u1,
90 Standard_Real& v1) {
91 Standard_Real f,l,lmf;
92 GeomAbs_SurfaceType typs1 = myHS1->GetType();
93
94 Standard_Boolean myHS1IsUPeriodic,myHS1IsVPeriodic;
95 switch (typs1) {
96 case GeomAbs_Cylinder:
97 case GeomAbs_Cone:
98 case GeomAbs_Sphere:
99 {
100 myHS1IsUPeriodic = Standard_True;
101 myHS1IsVPeriodic = Standard_False;
102 break;
103 }
104 case GeomAbs_Torus:
105 {
106 myHS1IsUPeriodic = myHS1IsVPeriodic = Standard_True;
107 break;
108 }
109 default:
110 {
111 myHS1IsUPeriodic = myHS1IsVPeriodic = Standard_False;
112 break;
113 }
114 }
115 if(myHS1IsUPeriodic) {
c6541a0c 116 lmf = M_PI+M_PI; //-- myHS1->UPeriod();
7fd59977 117 f = myHS1->FirstUParameter();
118 l = myHS1->LastUParameter();
119 while(u1 < f) { u1+=lmf; }
120 while(u1 > l) { u1-=lmf; }
121 }
122 if(myHS1IsVPeriodic) {
c6541a0c 123 lmf = M_PI+M_PI; //-- myHS1->VPeriod();
7fd59977 124 f = myHS1->FirstVParameter();
125 l = myHS1->LastVParameter();
126 while(v1 < f) { v1+=lmf; }
127 while(v1 > l) { v1-=lmf; }
128 }
129}
130
131
132static void LineConstructor(Contap_TheSequenceOfLine& slin,
133 const Handle(TheTopolTool)& Domain,
134 Contap_TheLine& L,
135 const TheSurface& Surf) {
136
137 //-- ------------------------------------------------------------
138 //-- on decoupe la ligne en portions entre 2 vertex
139 Standard_Real Tol = Precision::PConfusion();
140 Contap_IType typl = L.TypeContour();
141 //-- cout<<"\n ----------- Ligne Constructor "<<endl;
142 if(typl == Contap_Walking) {
143 Standard_Real u1,v1,u2,v2;
144 Standard_Integer nbvtx = L.NbVertex();
145 //-- cout<<" WLine -> "<<nbvtx<<" vtx"<<endl;
146 for(Standard_Integer i=1;i<nbvtx;i++) {
7fd59977 147 Standard_Integer firstp = (Standard_Integer) L.Vertex(i).ParameterOnLine();
148 Standard_Integer lastp = (Standard_Integer) L.Vertex(i+1).ParameterOnLine();
7fd59977 149 if(firstp!=lastp) {
150 Standard_Integer pmid = (firstp+lastp)/2; //-- entiers
151 const IntSurf_PntOn2S& Pmid = L.Point(pmid);
152 Pmid.Parameters(u1,v1,u2,v2);
153 Recadre(Surf,u2,v2);
154 TopAbs_State in2 = Domain->Classify(gp_Pnt2d(u2,v2),Tol);
155 if(in2 == TopAbs_OUT) {
156 }
157 else {
158 //-- cout<<"ContapWLine : firtsp="<<firstp<<" lastp="<<lastp<<" Vtx:"<<i<<","<<i+1<<endl;
159 Handle(IntSurf_LineOn2S) LineOn2S = new IntSurf_LineOn2S();
160 Contap_TheLine Line;
161 for(Standard_Integer j=firstp; j<=lastp; j++) {
162 LineOn2S->Add(L.Point(j));
163 }
164 Line.SetLineOn2S(LineOn2S);
165 Contap_ThePoint pvtx = L.Vertex(i);
166 pvtx.SetParameter(1);
167 Line.Add(pvtx);
168
169 pvtx = L.Vertex(i+1);
170 pvtx.SetParameter(lastp-firstp+1);
171 Line.Add(pvtx);
172 Line.SetTransitionOnS(L.TransitionOnS());
173 slin.Append(Line);
174 }
175 }
176 }
177 }
178 else if(typl==Contap_Lin) {
179 Standard_Real u2,v2;// u1,v1;
180 Standard_Integer nbvtx = L.NbVertex();
181 //-- cout<<" Lin -> "<<nbvtx<<" vtx"<<endl;
182 for(Standard_Integer i=1;i<nbvtx;i++) {
183 Standard_Real firstp = L.Vertex(i).ParameterOnLine();
184 Standard_Real lastp = L.Vertex(i+1).ParameterOnLine();
185 if(firstp!=lastp) {
186 Standard_Real pmid = (firstp+lastp)*0.5;
187 gp_Pnt Pmid = ElCLib::Value(pmid,L.Line());
188 if(TheSurfaceTool::GetType(Surf)==GeomAbs_Cylinder) {
189 ElSLib::Parameters(TheSurfaceTool::Cylinder(Surf),Pmid,u2,v2);
190 }
191 else if(TheSurfaceTool::GetType(Surf)==GeomAbs_Cone) {
192 ElSLib::Parameters(TheSurfaceTool::Cone(Surf),Pmid,u2,v2);
193 }
194 else {
195 //-- cout<<" Pb ds Contap_ContourGen_2.gxx (type)"<<endl;
196 }
197
198 Recadre(Surf,u2,v2);
199 TopAbs_State in2 = Domain->Classify(gp_Pnt2d(u2,v2),Tol);
200 if(in2 == TopAbs_OUT) {
201 }
202 else {
203 //-- cout<<"Contap Lin : firtsp="<<firstp<<" lastp="<<lastp<<" Vtx:"<<i<<","<<i+1<<endl;
204 Contap_TheLine Line;
205 Line.SetValue(L.Line());
206 Contap_ThePoint pvtx = L.Vertex(i);
207 Line.Add(pvtx);
208
209 pvtx = L.Vertex(i+1);
210 Line.Add(pvtx);
211 Line.SetTransitionOnS(L.TransitionOnS());
212 slin.Append(Line);
213 }
214 }
215 }
216 }
217 else if(typl==Contap_Circle) {
218 Standard_Real u2,v2; //u1,v1,
219 Standard_Integer nbvtx = L.NbVertex();
220 //-- cout<<" Circ -> "<<nbvtx<<" vtx"<<endl;
221 Standard_Boolean novtx = Standard_True;
222 if(nbvtx) novtx=Standard_False;
223 for(Standard_Integer i=1;i<nbvtx || novtx;i++) {
c6541a0c 224 Standard_Real firstp=0,lastp=M_PI+M_PI;
7fd59977 225 if(novtx == Standard_False) {
226 firstp = L.Vertex(i).ParameterOnLine();
227 lastp = L.Vertex(i+1).ParameterOnLine();
228 }
229 if(Abs(firstp-lastp)>0.000000001) {
230 Standard_Real pmid = (firstp+lastp)*0.5;
231 gp_Pnt Pmid = ElCLib::Value(pmid,L.Circle());
232 if(TheSurfaceTool::GetType(Surf)==GeomAbs_Cylinder) {
233 ElSLib::Parameters(TheSurfaceTool::Cylinder(Surf),Pmid,u2,v2);
234 }
235 else if(TheSurfaceTool::GetType(Surf)==GeomAbs_Cone) {
236 ElSLib::Parameters(TheSurfaceTool::Cone(Surf),Pmid,u2,v2);
237 }
238 else if(TheSurfaceTool::GetType(Surf)==GeomAbs_Sphere) {
239 ElSLib::Parameters(TheSurfaceTool::Sphere(Surf),Pmid,u2,v2);
240 }
241 else {
242 //-- cout<<" Pb ds Contap_ContourGen_2.gxx (typep)"<<endl;
243 }
244
245 Recadre(Surf,u2,v2);
246 TopAbs_State in2 = Domain->Classify(gp_Pnt2d(u2,v2),Tol);
247 if(in2 == TopAbs_OUT) {
248 }
249 else {
250 //-- cout<<"Contap Circle : firtsp="<<firstp<<" lastp="<<lastp<<" Vtx:"<<i<<","<<i+1<<endl;
251 Contap_TheLine Line;
252 Line.SetValue(L.Circle());
253 if(novtx == Standard_False) {
254 Contap_ThePoint pvtx = L.Vertex(i);
255 Line.Add(pvtx);
256 pvtx = L.Vertex(i+1);
257 Line.Add(pvtx);
258 }
259 Line.SetTransitionOnS(L.TransitionOnS());
260 slin.Append(Line);
261 }
262 }
263 novtx = Standard_False;
264 }
265 if(nbvtx) {
266 Standard_Real firstp = L.Vertex(nbvtx).ParameterOnLine();
c6541a0c 267 Standard_Real lastp = L.Vertex(1).ParameterOnLine() + M_PI+M_PI;
7fd59977 268 if(Abs(firstp-lastp)>0.0000000001) {
269 Standard_Real pmid = (firstp+lastp)*0.5;
270 gp_Pnt Pmid = ElCLib::Value(pmid,L.Circle());
271 if(TheSurfaceTool::GetType(Surf)==GeomAbs_Cylinder) {
272 ElSLib::Parameters(TheSurfaceTool::Cylinder(Surf),Pmid,u2,v2);
273 }
274 else if(TheSurfaceTool::GetType(Surf)==GeomAbs_Cone) {
275 ElSLib::Parameters(TheSurfaceTool::Cone(Surf),Pmid,u2,v2);
276 }
277 else if(TheSurfaceTool::GetType(Surf)==GeomAbs_Sphere) {
278 ElSLib::Parameters(TheSurfaceTool::Sphere(Surf),Pmid,u2,v2);
279 }
280 else {
281 //-- cout<<" Pb ds Contap_ContourGen_2.gxx (typep)"<<endl;
282 }
283
284 Recadre(Surf,u2,v2);
285 TopAbs_State in2 = Domain->Classify(gp_Pnt2d(u2,v2),Tol);
286 if(in2 == TopAbs_OUT) {
287 }
288 else {
289 //-- cout<<"Contap Circle *Compl* : firtsp="<<firstp<<" lastp="<<lastp<<" Vtx:"<<i<<","<<i+1<<endl;
290 Contap_TheLine Line;
291 Line.SetValue(L.Circle());
292 Contap_ThePoint pvtx = L.Vertex(nbvtx);
293 Line.Add(pvtx);
294
c6541a0c 295 pvtx = L.Vertex(1); pvtx.SetParameter(pvtx.ParameterOnLine()+M_PI+M_PI);
7fd59977 296 Line.Add(pvtx);
297 Line.SetTransitionOnS(L.TransitionOnS());
298 slin.Append(Line);
299 }
300 }
301 }
302 }
303 else {
304 //-- cout<<" ni WLine ni Lin ni Circ "<<endl;
305 slin.Append(L);
306 }
307 //--
308}
309
310//-- --------------------------------------------------------------------------------
311
312
313
314static void KeepInsidePoints(const Contap_TheSearchInside& solins,
315 const Contap_TheSearch& solrst,
316 Contap_TheSurfFunction& Func,
317 IntSurf_SequenceOfInteriorPoint& seqpins)
318
319{
320 Standard_Integer Nba = solrst.NbSegments();
321 if (Nba <= 0) return;
322 Standard_Integer Nbp,indp,inda;
323 Standard_Real U,V,paramproj;
324 gp_Pnt2d toproj,Ptproj;
325 Standard_Boolean projok,tokeep;
326 const TheSurface& Surf = Func.Surface();
327
328 Nbp = solins.NbPoints();
329 for (indp=1; indp <= Nbp; indp++) {
330 tokeep = Standard_True;
331 const IntSurf_InteriorPoint& pti = solins.Value(indp);
332 pti.Parameters(U,V);
333 toproj = gp_Pnt2d(U,V);
334 for (inda = 1; inda <= Nba; inda++) {
335 const TheArc& thearc = solrst.Segment(inda).Curve();
336 projok = TheContTool::Project(thearc,toproj,paramproj,Ptproj);
337 if (projok) {
338 gp_Pnt pprojete = TheSurfaceTool::Value(Surf,Ptproj.X(),Ptproj.Y());
339 if (pti.Value().Distance(pprojete) <= Precision::Confusion()) {
340 tokeep = Standard_False;
341 break;
342 }
343 }
344 }
345 if (tokeep) {
346 seqpins.Append(pti);
347 }
348 }
349}
350
351
352static void ComputeTangency (const Contap_TheSearch& solrst,
353 const Handle(TheTopolTool)& Domain,
354 Contap_TheSurfFunction& Func,
355 IntSurf_SequenceOfPathPoint& seqpdep,
356 TColStd_Array1OfInteger& Destination)
357{
358
359 Standard_Integer i,k;
360 Standard_Integer NbPoints = solrst.NbPoints();
361 Standard_Integer seqlength = 0;
362
363 Standard_Real theparam,test;
364 Standard_Boolean fairpt;
365 TopAbs_Orientation arcorien,vtxorien;
366 Standard_Boolean ispassing;
367
368 math_Vector X(1, 2);
369 math_Vector F(1, 1);
370 math_Matrix D(1, 1, 1, 2);
371
372 gp_Vec normale, vectg, tg3drst,v1,v2;
373 gp_Dir2d dirtg;
374 gp_Vec2d tg2drst;
375 gp_Pnt2d pt2d;
376
377 IntSurf_PathPoint PPoint;
378 const TheSurface& Surf = Func.Surface();
379
380 for (i=1; i<= NbPoints; i++) {
381
382 if (Destination(i) == 0) {
383
384 const Contap_ThePathPointOfTheSearch& PStart = solrst.Point(i);
385 const TheArc& thearc = PStart.Arc();
386 theparam = PStart.Parameter();
387 gp_Pnt2d Ptoproj=TheArcTool::Value(thearc,theparam);
388 //-- lbr le 15 mai 97
389 //-- On elimine les points qui sont egalement present sur une restriction solution
390 Standard_Boolean SurUneRestrictionSolution = Standard_False;
391 for(Standard_Integer restriction=1;
392 SurUneRestrictionSolution==Standard_False && restriction<=solrst.NbSegments();
393 restriction++) {
394 const TheArc& thearcsol = solrst.Segment(restriction).Curve();
395 Standard_Real paramproj;
396 gp_Pnt2d pproj;
397 Standard_Boolean projok = TheContTool::Project(thearcsol,Ptoproj,paramproj,pproj);
398 if(projok) {
399 //gp_Pnt pprojete = TheSurfaceTool::Value(Surf,Ptoproj.X(),Ptoproj.Y());
400 //IFV - begin
401 gp_Pnt pprojete = TheSurfaceTool::Value(Surf,pproj.X(),pproj.Y());
402 //IFV - end
403 if ((PStart.Value()).Distance(pprojete) <= Precision::Confusion()) {
404 SurUneRestrictionSolution = Standard_True;
405 }
406 }
407 }
408 if(SurUneRestrictionSolution == Standard_False) {
409 arcorien = Domain->Orientation(thearc);
410 ispassing = (arcorien == TopAbs_INTERNAL ||
411 arcorien == TopAbs_EXTERNAL);
412
413 TheArcTool::D1(thearc,theparam,pt2d,tg2drst);
414 X(1) = pt2d.X();
415 X(2) = pt2d.Y();
416 PPoint.SetValue(PStart.Value(),X(1),X(2));
417
418 Func.Values(X,F,D);
419 if (Func.IsTangent()) {
420 PPoint.SetTangency(Standard_True);
421 Destination(i) = seqlength+1;
422 if (!PStart.IsNew()) {
423 const TheVertex& vtx = PStart.Vertex();
424 for (k=i+1; k<=NbPoints; k++) {
425 if (Destination(k) ==0) {
426 const Contap_ThePathPointOfTheSearch& PStart2 = solrst.Point(k);
427 if (!PStart2.IsNew()) {
428 const TheVertex& vtx2 = PStart2.Vertex();
429 if (Domain->Identical(vtx,vtx2)) {
430 const TheArc& thearc2 = PStart2.Arc();
431 theparam = PStart2.Parameter();
432 arcorien = Domain->Orientation(thearc2);
433 ispassing = ispassing && (arcorien == TopAbs_INTERNAL ||
434 arcorien == TopAbs_EXTERNAL);
435
436 pt2d = TheArcTool::Value(thearc2,theparam);
437 X(1) = pt2d.X();
438 X(2) = pt2d.Y();
439 PPoint.AddUV(X(1),X(2));
440 Destination(k) = seqlength+1;
441 }
442 }
443 }
444 }
445 }
446 PPoint.SetPassing(ispassing);
447 seqpdep.Append(PPoint);
448 seqlength++;
449 }
450 else { // on a un point de depart potentiel
451
452 vectg = Func.Direction3d();
453 dirtg = Func.Direction2d();
454
455 gp_Pnt ptbid;
456 // TheSurfaceTool::D1(Surf,X(1),X(2),ptbid,v1,v2);
457 Contap_TheSurfProps::DerivAndNorm(Surf,X(1),X(2),ptbid,v1,v2,normale);
458 tg3drst = tg2drst.X()*v1 + tg2drst.Y()*v2;
459 // normale = v1.Crossed(v2);
460 if(normale.SquareMagnitude() < RealEpsilon()) {
461 //-- cout<<"\n*** Contap_ContourGen_2.gxx Normale Nulle en U:"<<X(1)<<" V:"<<X(2)<<endl;
462 }
463 else {
464 test = vectg.Dot(normale.Crossed(tg3drst));
465
466 if (PStart.IsNew()) {
467 Standard_Real tbis = vectg.Normalized().Dot(tg3drst.Normalized());
468 if (Abs(tbis) < 1.-tole) {
469
470 if ((test < 0. && arcorien == TopAbs_FORWARD) ||
471 (test > 0. && arcorien == TopAbs_REVERSED)) {
472 vectg.Reverse();
473 dirtg.Reverse();
474 }
475 PPoint.SetDirections(vectg,dirtg);
476 }
477 else { // on garde le point comme point d`arret (tangent)
478 PPoint.SetTangency(Standard_True);
479 }
480 PPoint.SetPassing(ispassing);
481 Destination(i) = seqlength+1;
482 seqpdep.Append(PPoint);
483 seqlength++;
484 }
485 else { // traiter la transition complexe
486 gp_Dir bidnorm(1.,1.,1.);
487
488 Standard_Boolean tobeverified = Standard_False;
489 TopAbs_Orientation LocTrans;
490 TopTrans_CurveTransition comptrans;
491 comptrans.Reset(vectg,bidnorm,0.);
492 if (arcorien != TopAbs_INTERNAL &&
493 arcorien != TopAbs_EXTERNAL) {
494 // pour essai
495 const TheVertex& vtx = PStart.Vertex();
496 vtxorien = Domain->Orientation(vtx);
497 test = test/(vectg.Magnitude());
498 test = test/((normale.Crossed(tg3drst)).Magnitude());
499
500 if (Abs(test) <= tole) {
501 tobeverified = Standard_True;
502 LocTrans = TopAbs_EXTERNAL; // et pourquoi pas INTERNAL
503 }
504 else {
505 if ((test > 0.)&& arcorien == TopAbs_FORWARD ||
506 (test < 0.)&& arcorien == TopAbs_REVERSED){
507 LocTrans = TopAbs_FORWARD;
508 }
509 else {
510 LocTrans = TopAbs_REVERSED;
511 }
512 if (arcorien == TopAbs_REVERSED) {tg3drst.Reverse();} // pas deja fait ???
513 }
514
515 comptrans.Compare(tole,tg3drst,bidnorm,0.,LocTrans,vtxorien);
516 }
517 Destination(i) = seqlength+1;
518 for (k= i+1; k<=NbPoints; k++) {
519 if (Destination(k) == 0) {
520 const Contap_ThePathPointOfTheSearch& PStart2 = solrst.Point(k);
521 if (!PStart2.IsNew()) {
522 const TheVertex& vtx2 = PStart2.Vertex();
523 if (Domain->Identical(PStart.Vertex(),vtx2)) {
524 const TheArc& thearc2 = PStart2.Arc();
525 theparam = PStart2.Parameter();
526 arcorien = Domain->Orientation(thearc2);
527
528 TheArcTool::D1(thearc2,theparam,pt2d,tg2drst);
529 X(1) = pt2d.X();
530 X(2) = pt2d.Y();
531 PPoint.AddUV(X(1),X(2));
532
533 if (arcorien != TopAbs_INTERNAL &&
534 arcorien != TopAbs_EXTERNAL) {
535 ispassing = Standard_False;
536 tg3drst = tg2drst.X()*v1 + tg2drst.Y()*v2;
537 test = vectg.Dot(normale.Crossed(tg3drst));
538 test = test/(vectg.Magnitude());
539 test = test /((normale.Crossed(tg3drst)).Magnitude());
540
541 vtxorien = Domain->Orientation(vtx2);
542 if (Abs(test) <= tole) {
543 tobeverified = Standard_True;
544 LocTrans = TopAbs_EXTERNAL; // et pourquoi pas INTERNAL
545 }
546 else {
547 if ((test > 0.)&& arcorien == TopAbs_FORWARD ||
548 (test < 0.)&& arcorien == TopAbs_REVERSED){
549 LocTrans = TopAbs_FORWARD;
550 }
551 else {
552 LocTrans = TopAbs_REVERSED;
553 }
554 if (arcorien == TopAbs_REVERSED) {tg3drst.Reverse();} //deja fait????
555 }
556
557 comptrans.Compare(tole,tg3drst,bidnorm,0.,LocTrans,vtxorien);
558 }
559 Destination(k) = seqlength+1;
560 }
561 }
562 }
563 }
564 fairpt = Standard_True;
565 if (!ispassing) {
566 TopAbs_State Before = comptrans.StateBefore();
567 TopAbs_State After = comptrans.StateAfter();
568 if ((Before == TopAbs_UNKNOWN)||(After == TopAbs_UNKNOWN)) {
569 fairpt = Standard_False;
570 }
571 else if (Before == TopAbs_IN) {
572 if (After == TopAbs_IN) {
573 ispassing = Standard_True;
574 }
575 else {
576 vectg.Reverse();
577 dirtg.Reverse();
578 }
579 }
580 else {
581 if (After !=TopAbs_IN) {
582 fairpt = Standard_False;
583 }
584 }
585 }
586
587 // evite de partir le long d une restriction solution
588
589 if (fairpt && tobeverified) {
590 for (k=i; k <=NbPoints ; k++) {
591 if (Destination(k)==seqlength + 1) {
592 theparam = solrst.Point(k).Parameter();
593 const TheArc& thearc2 = solrst.Point(k).Arc();
594 arcorien = Domain->Orientation(thearc2);
595
596 if (arcorien == TopAbs_FORWARD ||
597 arcorien == TopAbs_REVERSED) {
598 TheArcTool::D1(thearc2,theparam,pt2d,tg2drst);
599 tg3drst = tg2drst.X()*v1 + tg2drst.Y()*v2;
600 vtxorien = Domain->Orientation(solrst.Point(k).Vertex());
601 if ((arcorien == TopAbs_FORWARD &&
602 vtxorien == TopAbs_REVERSED) ||
603 (arcorien == TopAbs_REVERSED &&
604 vtxorien == TopAbs_FORWARD)) {
605 tg3drst.Reverse();
606 }
607 test = vectg.Normalized().Dot(tg3drst.Normalized());
608 if (test >= 1. - tole) {
609 fairpt = Standard_False;
610 break;
611 }
612 }
613 }
614 }
615 }
616
617 if (fairpt) {
618 PPoint.SetDirections(vectg,dirtg);
619 PPoint.SetPassing(ispassing);
620 seqpdep.Append(PPoint);
621 seqlength++;
622 }
623 else { // il faut remettre en "ordre" si on ne garde pas le point.
624 for (k=i; k <=NbPoints ; k++) {
625 if (Destination(k)==seqlength + 1) {
626 Destination(k) = -Destination(k);
627 }
628 }
629 }
630 }
631 }
632 }
633 }
634 }
635 }
636}
637
638
639IntSurf_TypeTrans ComputeTransitionOnLine(Contap_TheSurfFunction& SFunc,
640 const Standard_Real u,
641 const Standard_Real v,
642 const gp_Vec& tgline)
643{
644 gp_Vec d1u,d1v;
645 gp_Pnt pntbid;
646 //gp_Vec tglineuv;
647
648 TheSurfaceTool::D1(SFunc.Surface(),u,v,pntbid,d1u,d1v);
649
650 //------------------------------------------------------
651 //-- Calcul de la tangente dans l espace uv ---
652 //------------------------------------------------------
653
654 Standard_Real det,d1uT,d1vT,normu2,normv2,d1ud1v,alpha,beta;
655 d1uT = d1u.Dot(tgline);
656 d1vT = d1v.Dot(tgline);
657 normu2 = d1u.Dot(d1u);
658 normv2 = d1v.Dot(d1v);
659 d1ud1v = d1u.Dot(d1v);
660 det = normu2 * normv2 - d1ud1v * d1ud1v;
661 if(det<RealEpsilon()) {
662 //-- On ne doit pas passer ici !!
663 //-- cout<<" Probleme !!!"<<endl ;
664 return IntSurf_Undecided;
665 }
666
667 alpha = (d1uT * normv2 - d1vT * d1ud1v)/det;
668 beta = (normu2 * d1vT - d1ud1v * d1uT)/det;
669 //-----------------------------------------------------
670 //-- Calcul du Gradient de la fonction Utilisee --
671 //-- pour le contour apparent --
672 //-----------------------------------------------------
673
674 Standard_Real v1,v2;
675 math_Vector X(1,2);
676 math_Matrix Df(1,1,1,2);
677 X(1) = u;
678 X(2) = v;
679 SFunc.Derivatives(X,Df);
680 v1 = Df(1,1);
681 v2 = Df(1,2);
682
683 //-----------------------------------------------------
684 //-- On calcule si la fonction --
685 //-- F(.) = Normale . Dir_Regard --
686 //-- Croit Losrque l on se deplace sur la Gauche --
687 //-- de la direction de deplacement sur la ligne. --
688 //-----------------------------------------------------
689
690 det = -v1*beta + v2*alpha;
691
692 if(det<RealEpsilon()) { // revoir le test jag 940620
693 return IntSurf_Undecided;
694 }
695 if(det>0.0) {
696 return(IntSurf_Out);
697 }
698 return(IntSurf_In);
699}
700
701
702void ProcessSegments (const Contap_TheSearch& solrst,
703 Contap_TheSequenceOfLine& slin,
704 const Standard_Real TolArc,
705 Contap_TheSurfFunction& SFunc,
706 const Handle(TheTopolTool)& Domain)
707
708{
709 Standard_Integer i,j,k;
710 Standard_Integer nbedg = solrst.NbSegments();
711 Standard_Integer Nblines,Nbpts;
712
713 TheArc arcRef;
714 Contap_ThePoint ptvtx;
715
716 Contap_ThePathPointOfTheSearch PStartf,PStartl;
717
718 Standard_Boolean dofirst,dolast,procf,procl;
7fd59977 719 Standard_Real paramf =0.,paraml =0.,U;
7fd59977 720 Contap_TheLine theline;
721
722 gp_Vec tgline;//,norm1,norm2;
723 gp_Pnt valpt;
724
725 gp_Vec d1u,d1v;
726 gp_Pnt2d p2d;
727 gp_Vec2d d2d;
728
729
730 for (i = 1; i <= nbedg; i++) {
731
732 const Contap_TheSegmentOfTheSearch& thesegsol = solrst.Segment(i);
733 theline.SetValue(thesegsol.Curve());
734
735// Traitement des points debut/fin du segment solution.
736
737 dofirst = Standard_False;
738 dolast = Standard_False;
739 procf = Standard_False;
740 procl = Standard_False;
741
742 if (thesegsol.HasFirstPoint()) {
743 dofirst = Standard_True;
744 PStartf = thesegsol.FirstPoint();
745 paramf = PStartf.Parameter();
746 }
747 if (thesegsol.HasLastPoint()) {
748 dolast = Standard_True;
749 PStartl = thesegsol.LastPoint();
750 paraml = PStartl.Parameter();
751 }
752
753 // determination de la transition
754 if (dofirst && dolast) {
755 U = (paramf+paraml)/2.;
756 }
757 else if (dofirst) {
758 U = paramf + 1.0;
759 }
760 else if (dolast) {
761 U = paraml - 1.0;
762 }
763 else {
764 U = 0.0;
765 }
766
767 TheArcTool::D1(thesegsol.Curve(),U,p2d,d2d);
768 TheSurfaceTool::D1(SFunc.Surface(),p2d.X(),p2d.Y(),valpt,d1u,d1v);
769 tgline.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
770 IntSurf_TypeTrans tral =
771 ComputeTransitionOnLine(SFunc,p2d.X(),p2d.Y(),tgline);
772
773 theline.SetTransitionOnS(tral);
774
775
776 if (dofirst || dolast) {
777 Nblines = slin.Length();
778 for (j=1; j<=Nblines; j++) {
779 Nbpts = slin(j).NbVertex();
780 for (k=1; k<=Nbpts;k++) {
781 ptvtx = slin(j).Vertex(k);
782 if (dofirst) {
783 if (ptvtx.Value().Distance(PStartf.Value()) <=TolArc) {
784 slin(j).Vertex(k).SetMultiple();
785 ptvtx.SetMultiple();
786 ptvtx.SetParameter(paramf);
787 theline.Add(ptvtx);
788 procf=Standard_True;
789 }
790 }
791 if (dolast) {
792 if (ptvtx.Value().Distance(PStartl.Value()) <=TolArc) {
793 slin(j).Vertex(k).SetMultiple();
794 ptvtx.SetMultiple();
795 ptvtx.SetParameter(paraml);
796 theline.Add(ptvtx);
797 procl=Standard_True;
798 }
799 }
800 }
801// Si on a traite le pt debut et/ou fin, on ne doit pas recommencer si
802// il (ils) correspond(ent) a un point multiple.
803
804 if (procf) {
805 dofirst = Standard_False;
806 }
807 if (procl) {
808 dolast = Standard_False;
809 }
810 }
811 }
812
813// Si on n a pas trouve le point debut et./ou fin sur une des lignes
814// d intersection, il faut quand-meme le placer sur la restriction solution
815
816 if (dofirst) {
817
818 p2d = TheArcTool::Value(thesegsol.Curve(),paramf);
819 ptvtx.SetValue(PStartf.Value(),p2d.X(),p2d.Y());
820 ptvtx.SetParameter(paramf);
821 if (! PStartf.IsNew()) {
822 ptvtx.SetVertex(PStartf.Vertex());
823 }
824 theline.Add(ptvtx);
825 }
826 if (dolast) {
827 p2d = TheArcTool::Value(thesegsol.Curve(),paraml);
828 ptvtx.SetValue(PStartl.Value(),p2d.X(),p2d.Y());
829 ptvtx.SetParameter(paraml);
830 if (! PStartl.IsNew()) {
831 ptvtx.SetVertex(PStartl.Vertex());
832 }
833 theline.Add(ptvtx);
834 }
835
836 // il faut chercher le points internal sur les restrictions solutions.
837 if (thesegsol.HasFirstPoint() && thesegsol.HasLastPoint()) {
838 ComputeInternalPointsOnRstr(theline,paramf,paraml,SFunc);
839 }
840 LineConstructor(slin,Domain,theline,SFunc.Surface()); //-- lbr
841 //-- slin.Append(theline);
842 theline.Clear();
843 }
844}
845
846void ComputeInternalPointsOnRstr
847 (Contap_TheLine& Line,
848 const Standard_Real Paramf,
849 const Standard_Real Paraml,
850 Contap_TheSurfFunction& SFunc)
851{
852 // On recherche les points ou la tangente a la ligne de contour et
853 // la direction sont alignees.
854 // 1ere etape : recherche de changement de signe.
855 // 2eme etape : localisation de la solution par dichotomie
856
857
858 Standard_Integer indexinf,indexsup,i;
859 gp_Vec tgt, vecref, vectest, vtestb, vecregard,d1u,d1v;
860 gp_Pnt pcour;
861 gp_Pnt2d p2d;
862 gp_Vec2d d2d;
733a0e55 863 Standard_Boolean found,ok = Standard_False,toutvu,solution;
7fd59977 864 Standard_Real paramp,paraminf,paramsup,toler;
865
866 if (Line.TypeContour() != Contap_Restriction) {
867 return;
868 }
869
870 const TheArc& thearc = Line.Arc();
871
872 const TheSurface& Surf = SFunc.Surface();
873 Contap_TFunction TypeFunc(SFunc.FunctionType());
874
875 Standard_Integer Nbpnts = TheContTool::NbSamplesOnArc(thearc);
876 indexinf = 1;
877 vecregard = SFunc.Direction();
878 toler = TheArcTool::Resolution(thearc,Precision::Confusion());
879 found = Standard_False;
880
881 do {
882 paraminf = ((Nbpnts-indexinf)*Paramf + (indexinf-1)*Paraml)/(Nbpnts-1);
883 TheArcTool::D1(thearc,paraminf,p2d,d2d);
884 TheSurfaceTool::D1(Surf,p2d.X(),p2d.Y(),pcour,d1u,d1v);
885 tgt.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
886
887 if (tgt.Magnitude() > gp::Resolution()) {
888 if (TypeFunc == Contap_ContourPrs || TypeFunc==Contap_DraftPrs) {
889 vecregard.SetXYZ(pcour.XYZ()-SFunc.Eye().XYZ());
890 }
891 vecref = vecregard.Crossed(tgt);
892
893 if (vecref.Magnitude() <= gp::Resolution()) {
894 indexinf++;
895 }
896 else {
897 found = Standard_True;
898 }
899 }
900 else {
901 indexinf++;
902 }
903 } while ((indexinf <= Nbpnts) && (!found));
904
905
906 indexsup = indexinf +1;
907 toutvu = (indexsup > Nbpnts);
908 while (!toutvu) {
909 paramsup = ((Nbpnts-indexsup)*Paramf + (indexsup-1)*Paraml)/(Nbpnts-1);
910 TheArcTool::D1(thearc,paramsup,p2d,d2d);
911 TheSurfaceTool::D1(Surf,p2d.X(),p2d.Y(),pcour,d1u,d1v);
912 tgt.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
913
914 if (tgt.Magnitude() > gp::Resolution()) {
915 if (TypeFunc == Contap_ContourPrs || TypeFunc==Contap_DraftPrs) {
916 vecregard.SetXYZ(pcour.XYZ()-SFunc.Eye().XYZ());
917 }
918 vectest = vecregard.Crossed(tgt);
919 }
920 else {
921 vectest = gp_Vec(0.,0.,0.);
922 }
923 if (vectest.Magnitude() <= gp::Resolution()) {
924 // On cherche un vrai changement de signe
925 indexsup++;
926 }
927 else {
928 if (vectest.Dot(vecref) < 0.) {
929 // Essayer de converger
930 // cout << "Changement de signe detecte" << endl;
931 solution = Standard_False;
932 while (!solution) {
933 paramp = (paraminf+paramsup)/2.;
934 TheArcTool::D1(thearc,paramp,p2d,d2d);
935 TheSurfaceTool::D1(Surf,p2d.X(),p2d.Y(),pcour,d1u,d1v);
936 tgt.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
937
938 if (tgt.Magnitude() > gp::Resolution()) {
939 if (TypeFunc == Contap_ContourPrs || TypeFunc==Contap_DraftPrs) {
940 vecregard.SetXYZ(pcour.XYZ()-SFunc.Eye().XYZ());
941 }
942 vtestb = vecregard.Crossed(tgt);
943 }
944 else {
945 vtestb = gp_Vec(0.,0.,0.);
946 }
947
948 if ((vtestb.Magnitude() <= gp::Resolution())||
949 (Abs(paramp-paraminf) <= toler) ||
950 (Abs(paramp-paramsup) <= toler)) {
951 // on est a la solution
952 solution = Standard_True;
953 ok = Standard_True;
954 }
955 else if (vtestb.Dot(vecref) < 0.) {
956 paramsup = paramp;
957 }
958 else {
959 paraminf = paramp;
960 }
961
962 }
963
964 if (ok) {
965 // On verifie que le point trouve ne correspond pas a un ou des
966 // vertex deja existant(s). On teste sur le parametre paramp.
967 for (i=1; i<=Line.NbVertex(); i++) {
968 Contap_ThePoint& thevtx = Line.Vertex(i);
969 if (Abs(thevtx.ParameterOnLine()-paramp) <= toler) {
970 thevtx.SetInternal();
971 ok = Standard_False; // on a correspondance
972 }
973 }
974 if (ok) { // il faut alors rajouter le point
975 Contap_ThePoint internalp(pcour,p2d.X(),p2d.Y());
976 internalp.SetParameter(paramp);
977 internalp.SetInternal();
978 Line.Add(internalp);
979 }
980 }
981 paramsup = ((Nbpnts-indexsup)*Paramf + (indexsup-1)*Paraml)/(Nbpnts-1);
982 }
983 vecref = vectest;
984 indexinf = indexsup;
985 indexsup++;
986 paraminf = paramsup;
987 }
988 toutvu = (indexsup > Nbpnts);
989 }
990}
991
992
993void ComputeInternalPoints
994 (Contap_TheLine& Line,
995 Contap_TheSurfFunction& SFunc,
996 const Standard_Real ureso,
997 const Standard_Real vreso)
998
999{
1000 // On recherche les points ou la tangente a la ligne de contour et
1001 // la direction sont alignees.
1002 // 1ere etape : recheche de changement de signe.
1003 // 2eme etape : localisation de la solution par simili dichotomie
1004
1005
1006 Standard_Integer indexinf,indexsup,index;
1007 gp_Vec tgt, vecref, vectest, vtestb, vecregard;
1008 //gp_Pnt pprec,pcour;
733a0e55
S
1009 Standard_Boolean found,ok = Standard_False,toutvu,solution;
1010 Standard_Real paramp = 0.,U,V;
7fd59977 1011
1012 math_Vector XInf(1,2),XSup(1,2),X(1,2),F(1,1);
1013 math_Matrix DF(1,1,1,2);
1014 math_Vector toler(1,2),infb(1,2),supb(1,2);
1015
1016 if (Line.TypeContour() != Contap_Walking) {
1017 return;
1018 }
1019
1020 Standard_Integer Nbpnts = Line.NbPnts();
1021 const TheSurface& Surf = SFunc.Surface();
1022 Contap_TFunction TypeFunc(SFunc.FunctionType());
1023
1024 toler(1) = ureso; //-- Trop long !!! TheSurfaceTool::UResolution(Surf,SFunc.Tolerance());
1025 toler(2) = vreso; //---Beaucoup trop long !!! TheSurfaceTool::VResolution(Surf,SFunc.Tolerance());
1026 infb(1) = TheSurfaceTool::FirstUParameter(Surf);
1027 infb(2) = TheSurfaceTool::FirstVParameter(Surf);
1028 supb(1) = TheSurfaceTool::LastUParameter(Surf);
1029 supb(2) = TheSurfaceTool::LastVParameter(Surf);
1030
1031 math_FunctionSetRoot rsnld(SFunc,toler,30);
1032
1033 indexinf = 1;
1034 vecregard = SFunc.Direction();
1035
1036 found = Standard_False;
1037 do {
1038 Line.Point(indexinf).ParametersOnS2(XInf(1),XInf(2));
1039 SFunc.Values(XInf,F,DF);
1040 if (!SFunc.IsTangent()) {
1041 tgt = SFunc.Direction3d();
1042 if (TypeFunc == Contap_ContourPrs || TypeFunc == Contap_DraftPrs) {
1043 vecregard.SetXYZ(Line.Point(indexinf).Value().XYZ()-SFunc.Eye().XYZ());
1044 }
1045 vecref = vecregard.Crossed(tgt);
1046
1047 if (vecref.Magnitude() <= gp::Resolution()) {
1048 indexinf++;
1049 }
1050 else {
1051 found = Standard_True;
1052 }
1053 }
1054 else {
1055 indexinf++;
1056 }
1057 } while ((indexinf <= Nbpnts) && (!found));
1058
1059
1060 indexsup = indexinf +1;
1061 toutvu = (indexsup > Nbpnts);
1062 while (!toutvu) {
1063 Line.Point(indexsup).ParametersOnS2(XSup(1),XSup(2));
1064 SFunc.Values(XSup,F,DF);
1065 if (!SFunc.IsTangent()) {
1066 tgt = SFunc.Direction3d();
1067
1068 if (TypeFunc == Contap_ContourPrs || TypeFunc == Contap_DraftPrs) {
1069 vecregard.SetXYZ(Line.Point(indexsup).Value().XYZ()-SFunc.Eye().XYZ());
1070 }
1071 vectest = vecregard.Crossed(tgt);
1072 }
1073 else {
1074 vectest = gp_Vec(0.,0.,0.);
1075 }
1076 if (vectest.Magnitude() <= gp::Resolution()) {
1077 // On cherche un vrai changement de signe
1078 indexsup++;
1079 }
1080 else {
1081 if (vectest.Dot(vecref) < 0.) {
1082 // Essayer de converger
1083 // cout << "Changement de signe detecte" << endl;
1084 solution = Standard_False;
1085 while (!solution) {
1086 X(1) = (XInf(1) + XSup(1)) /2.;
1087 X(2) = (XInf(2) + XSup(2)) /2.;
1088 rsnld.Perform(SFunc,X,infb,supb);
1089
1090 if (!rsnld.IsDone()) {
1091 cout << "Echec recherche internal points" << endl;
1092 solution = Standard_True;
1093 ok = Standard_False;
1094 }
1095 else {
1096
1097 rsnld.Root(X);
1098 SFunc.Values(X,F,DF);
1099 if (Abs(F(1)) <= SFunc.Tolerance()) {
1100
1101 if (!SFunc.IsTangent()) {
1102 tgt = SFunc.Direction3d();
1103 if (TypeFunc == Contap_ContourPrs ||
1104 TypeFunc == Contap_DraftPrs) {
1105 vecregard.SetXYZ(SFunc.Point().XYZ()-SFunc.Eye().XYZ());
1106 }
1107 vtestb = vecregard.Crossed(tgt);
1108 }
1109 else {
1110 vtestb = gp_Vec(0.,0.,0.);
1111 }
1112 if ((vtestb.Magnitude() <= gp::Resolution())||
1113 (Abs(X(1)-XInf(1)) <= toler(1)
1114 && Abs(X(2)-XInf(2)) <= toler(2)) ||
1115 (Abs(X(1)-XSup(1)) <= toler(1)
1116 && Abs(X(2)-XSup(2)) <= toler(2))) {
1117 // on est a la solution
1118 solution = Standard_True;
1119 ok = Standard_True;
1120 }
1121 else if (vtestb.Dot(vecref) < 0.) {
1122 XSup = X;
1123 }
1124 else {
1125 XInf = X;
1126 }
1127 }
1128 else { // on n est pas sur une solution
1129 cout << "Echec recherche internal points" << endl;
1130 solution = Standard_True;
1131 ok = Standard_False;
1132 }
1133 }
1134 }
1135
1136 if (ok) {
1137 Standard_Boolean newpoint = Standard_False;
1138 Line.Point(indexinf).ParametersOnS2(U,V);
1139 gp_Vec2d vinf(X(1)-U,X(2)-V);
1140 if (Abs(vinf.X()) <= toler(1) && Abs(vinf.Y()) <= toler(2)) {
1141 paramp = indexinf;
1142 }
1143 else {
1144 for (index = indexinf+1; index <= indexsup; index++) {
1145 Line.Point(index).ParametersOnS2(U,V);
1146 gp_Vec2d vsup(X(1)-U,X(2)-V);
1147 if (Abs(vsup.X()) <= toler(1) && Abs(vsup.Y()) <= toler(2)) {
1148 paramp = index;
1149 break;
1150 }
1151 else if (vinf.Dot(vsup) < 0.) {
1152 // on est entre les 2 points
1153 paramp = index;
1154 IntSurf_PntOn2S pt2s;
1155 pt2s.SetValue(SFunc.Point(),Standard_False,X(1),X(2));
1156 Line.LineOn2S()->InsertBefore(index,pt2s);
1157
1158 //-- Il faut decaler les parametres des vertex situes entre
1159 //-- index et NbPnts ###################################
1160 for(Standard_Integer v=1; v<=Line.NbVertex(); v++) {
1161 Contap_ThePoint& Vertex = Line.Vertex(v);
1162 if(Vertex.ParameterOnLine() >= index) {
1163 Vertex.SetParameter(Vertex.ParameterOnLine()+1);
1164 }
1165 }
1166
1167 Nbpnts = Nbpnts+1;
1168 indexsup = indexsup+1;
1169 newpoint = Standard_True;
1170 break;
1171 }
1172 else {
1173 vinf = vsup;
1174 }
1175 }
1176 }
1177
1178 Standard_Integer v;
1179 if (!newpoint) {
1180 // on est sur un point de cheminement. On regarde alors
1181 // la correspondance avec un vertex existant.
1182 newpoint = Standard_True;
1183 for (v=1; v<= Line.NbVertex(); v++) {
1184 Contap_ThePoint& Vertex = Line.Vertex(v);
1185 if(Vertex.ParameterOnLine() == paramp) {
1186 Vertex.SetInternal();
1187 newpoint = Standard_False;
1188 }
1189 }
1190 }
1191
1192 if (newpoint && paramp >1. && paramp < Nbpnts) {
1193 // on doit creer un nouveau vertex.
1194 Contap_ThePoint internalp(SFunc.Point(),X(1),X(2));
1195 internalp.SetParameter(paramp);
1196 internalp.SetInternal();
1197 Line.Add(internalp);
1198 }
1199 }
1200 Line.Point(indexsup).ParametersOnS2(XSup(1),XSup(2));
1201 }
1202 vecref = vectest;
1203 indexinf = indexsup;
1204 indexsup++;
1205 XInf = XSup;
1206 }
1207 toutvu = (indexsup > Nbpnts);
1208 }
1209}
1210
1211
1212void Contap_ContourGen::Perform
1213 (const Handle(TheTopolTool)& Domain) {
1214
1215 done = Standard_False;
1216 slin.Clear();
1217
1218 Standard_Integer i,j,k,Nbvt1,Nbvt2,ivt1,ivt2;
1219 Standard_Integer NbPointRst,NbPointIns;
1220 Standard_Integer Nblines, Nbpts, indfirst, indlast;
1221 Standard_Real U,V;
1222 gp_Pnt2d pt2d;
1223 gp_Vec2d d2d;
1224 gp_Pnt ptonsurf;
1225 gp_Vec d1u,d1v,normale,tgtrst,tgline;
1226 Standard_Real currentparam;
1227 IntSurf_Transition TLine,TArc;
1228
1229 Contap_TheLine theline;
1230 Contap_ThePoint ptdeb,ptfin;
1231 Contap_ThePathPointOfTheSearch PStartf,PStartl;
1232
1233// Standard_Real TolArc = 1.e-5;
1234 Standard_Real TolArc = Precision::Confusion();
1235
1236 const TheSurface& Surf = mySFunc.Surface();
1237
1238 Standard_Real EpsU = TheSurfaceTool::UResolution(Surf,Precision::Confusion());
1239 Standard_Real EpsV = TheSurfaceTool::VResolution(Surf,Precision::Confusion());
1240 Standard_Real Preci = Min(EpsU,EpsV);
1241// Standard_Real Fleche = 5.e-1;
1242// Standard_Real Pas = 5.e-2;
1243 Standard_Real Fleche = 0.01;
1244 Standard_Real Pas = 0.005;
1245 // lbr: Il y avait Pas 0.2 -> Manque des Inters sur restr ; devrait faire un mini de 5 pts par lignes
1246 //-- le 23 janvier 98 0.05 -> 0.01
1247
1248
1249 //-- ******************************************************************************** Janvier 98
1250 Bnd_Box B1; Standard_Boolean Box1OK = Standard_True;
1251
1252 Standard_Real Uinf = Surf->FirstUParameter();
1253 Standard_Real Vinf = Surf->FirstVParameter();
1254 Standard_Real Usup = Surf->LastUParameter();
1255 Standard_Real Vsup = Surf->LastVParameter();
1256
1257 Standard_Boolean Uinfinfinite = Precision::IsNegativeInfinite(Uinf);
1258 Standard_Boolean Usupinfinite = Precision::IsPositiveInfinite(Usup);
1259 Standard_Boolean Vinfinfinite = Precision::IsNegativeInfinite(Vinf);
1260 Standard_Boolean Vsupinfinite = Precision::IsPositiveInfinite(Vsup);
1261
1262 if( Uinfinfinite || Usupinfinite || Vinfinfinite || Vsupinfinite) {
1263 Box1OK = Standard_False;
1264 }
1265 else {
1266 BndLib_AddSurface::Add(Surf->Surface(),1e-8,B1);
1267 }
1268 Standard_Real x0,y0,z0,x1,y1,z1,dx,dy,dz;
1269 if(Box1OK) {
1270 B1.Get(x0,y0,z0,x1,y1,z1);
1271 dx=x1-x0;
1272 dy=y1-y0;
1273 dz=z1-z0;
1274 }
1275 else {
1276 dx=dy=dz=1.0;
1277 }
1278 if(dx<dy) dx=dy;
1279 if(dx<dz) dx=dz;
1280 if(dx>10000.0) dx=10000.0;
1281 Fleche*=dx;
1282 TolArc*=dx;
1283 //-- ********************************************************************************
1284
1285
1286 //gp_Pnt valpt;
1287
1288//jag 940616 SFunc.Set(1.e-8); // tolerance sur la fonction
1289 mySFunc.Set(Precision::Confusion()); // tolerance sur la fonction
1290
bda83605 1291 Standard_Boolean RecheckOnRegularity = Standard_True;
1292 solrst.Perform(myAFunc,Domain,TolArc,TolArc,RecheckOnRegularity);
7fd59977 1293
1294 if (!solrst.IsDone()) {
1295 return;
1296 }
1297
1298 NbPointRst = solrst.NbPoints();
1299 IntSurf_SequenceOfPathPoint seqpdep;
1300 TColStd_Array1OfInteger Destination(1,NbPointRst+1);
1301 Destination.Init(0);
1302 if (NbPointRst != 0) {
1303 ComputeTangency(solrst,Domain,mySFunc,seqpdep,Destination);
1304 }
1305
1306 //jag 940616 solins.Perform(SFunc,Surf,Domain,1.e-6); // 1.e-6 : tolerance dans l espace.
1307 solins.Perform(mySFunc,Surf,Domain,Precision::Confusion());
1308
1309 NbPointIns = solins.NbPoints();
1310 IntSurf_SequenceOfInteriorPoint seqpins;
1311
1312 if (NbPointIns != 0) {
1313 Standard_Boolean bKeepAllPoints = Standard_False;
1314 //IFV begin
1315 if(solrst.NbSegments() <= 0) {
1316 if(mySFunc.FunctionType() == Contap_ContourStd) {
1317 const TheSurface& Surf = mySFunc.Surface();
1318 if(TheSurfaceTool::GetType(Surf) == GeomAbs_Torus) {
1319 gp_Torus aTor = TheSurfaceTool::Torus(Surf);
1320 gp_Dir aTorDir = aTor.Axis().Direction();
1321 gp_Dir aProjDir = mySFunc.Direction();
1322
1323 if(aTorDir.Dot(aProjDir) < Precision::Confusion()) {
1324 bKeepAllPoints = Standard_True;
1325 }
1326 }
1327 }
1328 }
1329
1330 if(bKeepAllPoints) {
1331 Standard_Integer Nbp = solins.NbPoints(), indp;
1332 for (indp=1; indp <= Nbp; indp++) {
1333 const IntSurf_InteriorPoint& pti = solins.Value(indp);
1334 seqpins.Append(pti);
1335 }
1336 }
1337 //IFV - end
1338 else {
1339 KeepInsidePoints(solins,solrst,mySFunc,seqpins);
1340 }
1341 }
1342
1343 if (seqpdep.Length() != 0 || seqpins.Length() != 0) {
1344
1345 Contap_TheIWalking iwalk(Preci,Fleche,Pas);
1346 iwalk.Perform(seqpdep,seqpins,mySFunc ,Surf);
1347 if(!iwalk.IsDone()) {
1348 return;
1349 }
1350
1351 Nblines = iwalk.NbLines();
1352 for (j=1; j<=Nblines; j++) {
1353 IntSurf_TypeTrans TypeTransOnS = IntSurf_Undecided;
1354 const Handle(Contap_TheIWLineOfTheIWalking)& iwline = iwalk.Value(j);
1355 Nbpts = iwline->NbPoints();
1356 theline.SetLineOn2S(iwline->Line());
1357
1358 // jag 941018 On calcule une seule fois la transition
1359
1360 tgline = iwline->TangentVector(k);
1361 iwline->Line()->Value(k).ParametersOnS2(U,V);
1362 TypeTransOnS = ComputeTransitionOnLine(mySFunc,U,V,tgline);
1363 theline.SetTransitionOnS(TypeTransOnS);
1364
1365 //---------------------------------------------------------------------
1366 //-- On ajoute a la liste des vertex les 1er et dernier points de la -
1367 //-- ligne de cheminement si ceux-ci ne sont pas presents -
1368 //---------------------------------------------------------------------
1369
1370 if (iwline->HasFirstPoint()) {
1371 indfirst = iwline->FirstPointIndex();
1372 const IntSurf_PathPoint& PPoint = seqpdep(indfirst);
1373 Standard_Integer themult = PPoint.Multiplicity();
1374 for (i=NbPointRst; i>=1; i--) {
1375 if (Destination(i) == indfirst) {
1376 PPoint.Parameters(themult,U,V);
1377 ptdeb.SetValue(PPoint.Value(),U,V);
1378 ptdeb.SetParameter(1.0);
1379
1380 const Contap_ThePathPointOfTheSearch& PStart = solrst.Point(i);
1381 const TheArc& currentarc = PStart.Arc();
1382 currentparam = PStart.Parameter();
1383 if (!iwline->IsTangentAtBegining()) {
1384
1385 TheArcTool::D1(currentarc,currentparam,pt2d,d2d);
1386 Contap_TheSurfProps::DerivAndNorm(Surf,pt2d.X(),pt2d.Y(),
1387 ptonsurf,d1u,d1v,normale);
1388 tgtrst = d2d.X()*d1u;
1389 tgtrst.Add(d2d.Y()*d1v);
1390
1391 IntSurf::MakeTransition(PPoint.Direction3d(),tgtrst,normale,
1392 TLine,TArc);
1393
1394 }
1395 else {// a voir. En effet, on a cheminer. Si on est sur un point
1396 // debut, on sait qu'on rentre dans la matiere
1397 TLine.SetValue();
1398 TArc.SetValue();
1399 }
1400
1401 ptdeb.SetArc(currentarc,currentparam,TLine,TArc);
1402
1403 if (!solrst.Point(i).IsNew()) {
1404 ptdeb.SetVertex(PStart.Vertex());
1405 }
1406 theline.Add(ptdeb);
1407 themult--;
1408 }
1409 }
1410 }
1411 else {
1412 iwline->Value(1).ParametersOnS2(U,V);
1413 ptdeb.SetValue(theline.Point(1).Value(),U,V);
1414 ptdeb.SetParameter(1.0);
1415 theline.Add(ptdeb);
1416 }
1417
1418 if (iwline->HasLastPoint()) {
1419 indlast = iwline->LastPointIndex();
1420 const IntSurf_PathPoint& PPoint = seqpdep(indlast);
1421 Standard_Integer themult = PPoint.Multiplicity();
1422 for (i=NbPointRst; i>=1; i--) {
1423 if (Destination(i) == indlast) {
1424 PPoint.Parameters(themult,U,V);
1425 ptfin.SetValue(PPoint.Value(),U,V);
1426 ptfin.SetParameter((Standard_Real)(Nbpts));
1427 const Contap_ThePathPointOfTheSearch& PStart = solrst.Point(i);
1428 const TheArc& currentarc = PStart.Arc();
1429 currentparam = PStart.Parameter();
1430
1431 if (!iwline->IsTangentAtEnd()) {
1432
1433 TheArcTool::D1(currentarc,currentparam,pt2d,d2d);
1434
1435 Contap_TheSurfProps::DerivAndNorm(Surf,pt2d.X(),pt2d.Y(),
1436 ptonsurf,d1u,d1v,normale);
1437 tgtrst = d2d.X()*d1u;
1438 tgtrst.Add(d2d.Y()*d1v);
1439 IntSurf::MakeTransition(PPoint.Direction3d().Reversed(),
1440 tgtrst,normale,TLine,TArc);
1441 }
1442 else {
1443 TLine.SetValue();
1444 TArc.SetValue();
1445 }
1446
1447 ptfin.SetArc(currentarc,currentparam,TLine,TArc);
1448
1449 if (!solrst.Point(i).IsNew()) {
1450 ptfin.SetVertex(PStart.Vertex());
1451 }
1452 theline.Add(ptfin);
1453 themult--;
1454 }
1455 }
1456 }
1457 else {
1458 iwline->Value(Nbpts).ParametersOnS2(U,V);
1459 ptfin.SetValue(theline.Point(Nbpts).Value(),U,V);
1460 ptfin.SetParameter((Standard_Real)(Nbpts));
1461 theline.Add(ptfin);
1462 }
1463
1464 ComputeInternalPoints(theline,mySFunc,EpsU,EpsV);
1465 LineConstructor(slin,Domain,theline,Surf); //-- lbr
1466 //-- slin.Append(theline);
1467 theline.ResetSeqOfVertex();
1468 }
1469
1470
1471 Nblines = slin.Length();
1472 for (j=1; j<=Nblines-1; j++) {
1473 const Contap_TheLine& theli = slin(j);
1474 Nbvt1 = theli.NbVertex();
1475 for (ivt1=1; ivt1<=Nbvt1; ivt1++) {
1476 if (!theli.Vertex(ivt1).IsOnArc()) {
1477 const gp_Pnt& pttg1 = theli.Vertex(ivt1).Value();
1478
1479 for (k=j+1; k<=Nblines;k++) {
1480 const Contap_TheLine& theli2 = slin(k);
1481 Nbvt2 = theli2.NbVertex();
1482 for (ivt2=1; ivt2<=Nbvt2; ivt2++) {
1483 if (!theli2.Vertex(ivt2).IsOnArc()) {
1484 const gp_Pnt& pttg2 = theli2.Vertex(ivt2).Value();
1485
1486 if (pttg1.Distance(pttg2) <= TolArc) {
1487 theli.Vertex(ivt1).SetMultiple();
1488 theli2.Vertex(ivt2).SetMultiple();
1489 }
1490 }
1491 }
1492 }
1493 }
1494 }
1495 }
1496 }
1497
1498 // jag 940620 On ajoute le traitement des restrictions solutions.
1499
1500 if (solrst.NbSegments() !=0) {
1501 ProcessSegments(solrst,slin,TolArc,mySFunc,Domain);
1502 }
1503
1504
1505 // Ajout crad pour depanner CMA en attendant mieux
1506 if (solrst.NbSegments() !=0) {
1507
1508 Nblines = slin.Length();
1509 for (j=1; j<=Nblines; j++) {
1510 const Contap_TheLine& theli = slin(j);
1511 if (theli.TypeContour() == Contap_Walking) {
1512 Nbvt1 = theli.NbVertex();
1513 for (ivt1=1; ivt1<=Nbvt1; ivt1++) {
1514 Contap_ThePoint& ptvt = theli.Vertex(ivt1);
1515 if (!ptvt.IsOnArc() && !ptvt.IsMultiple()) {
1516 Standard_Real Up,Vp;
1517 ptvt.Parameters(Up,Vp);
1518 gp_Pnt2d toproj(Up,Vp);
1519 Standard_Boolean projok;
1520 for (k=1; k<=Nblines;k++) {
1521 if (slin(k).TypeContour() == Contap_Restriction) {
1522 const TheArc& thearc = slin(k).Arc();
1523 Standard_Real paramproj;
1524 gp_Pnt2d Ptproj;
1525 projok = TheContTool::Project(thearc,toproj,paramproj,Ptproj);
1526
1527 if (projok) {
1528 Standard_Real dist = Ptproj.Distance(gp_Pnt2d(Up,Vp));
1529 if (dist <= Preci) {
1530 // Calcul de la transition
1531
1532 TheArcTool::D1(thearc,paramproj,Ptproj,d2d);
1533// TheSurfaceTool::D1(Surf,Ptproj.X(),Ptproj.Y(),
1534// ptonsurf,d1u,d1v);
1535// normale = d1u.Crossed(d1v);
1536
1537 Contap_TheSurfProps::DerivAndNorm
1538 (Surf,Ptproj.X(),Ptproj.Y(),ptonsurf,d1u,d1v,normale);
1539
1540 tgtrst = d2d.X()*d1u;
1541 tgtrst.Add(d2d.Y()*d1v);
1542 Standard_Integer Paraml =
1543 (Standard_Integer) ptvt.ParameterOnLine();
1544
1545 if (Paraml == theli.NbPnts()) {
1546 tgline = gp_Vec(theli.Point(Paraml-1).Value(),
1547 ptvt.Value());
1548 }
1549 else {
1550 tgline = gp_Vec(ptvt.Value(),
1551 theli.Point(Paraml+1).Value());
1552 }
1553 IntSurf::MakeTransition(tgline,tgtrst,normale,
1554 TLine,TArc);
1555 ptvt.SetArc(thearc,paramproj,TLine,TArc);
1556 ptvt.SetMultiple();
1557 ptdeb.SetValue(ptonsurf,Ptproj.X(),Ptproj.Y());
1558 ptdeb.SetParameter(paramproj);
1559 ptdeb.SetMultiple();
1560 slin(k).Add(ptdeb);
1561 break;
1562 }
1563 else {
1564 projok = Standard_False;
1565 }
1566 }
1567 }
1568 else {
1569 projok = Standard_False;
1570 }
1571 if (projok) {
1572 break;
1573 }
1574 }
1575 }
1576 }
1577 }
1578 }
1579 }
1580 done = Standard_True;
1581}
1582