0027930: XMT file conversion loops infinitely
[occt.git] / src / Contap / Contap_Contour.cxx
CommitLineData
e2065c2f 1// Created on: 1993-02-05
2// Created by: Jacques GOUSSARD
3// Copyright (c) 1993-1999 Matra Datavision
4// Copyright (c) 1999-2014 OPEN CASCADE SAS
5//
6// This file is part of Open CASCADE Technology software library.
7//
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
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.
13//
14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
16
e2065c2f 17
42cf5bc1 18#include <Adaptor3d_HSurface.hxx>
e2065c2f 19#include <Adaptor3d_HSurfaceTool.hxx>
42cf5bc1 20#include <Adaptor3d_TopolTool.hxx>
21#include <Bnd_Box.hxx>
22#include <BndLib_AddSurface.hxx>
e2065c2f 23#include <Contap_ContAna.hxx>
42cf5bc1 24#include <Contap_Contour.hxx>
e2065c2f 25#include <Contap_HContTool.hxx>
26#include <Contap_HCurve2dTool.hxx>
42cf5bc1 27#include <Contap_Line.hxx>
28#include <Contap_SurfFunction.hxx>
e2065c2f 29#include <Contap_SurfProps.hxx>
30#include <Contap_TheIWalking.hxx>
e2065c2f 31#include <Contap_ThePathPointOfTheSearch.hxx>
42cf5bc1 32#include <Contap_TheSegmentOfTheSearch.hxx>
33#include <ElCLib.hxx>
34#include <ElSLib.hxx>
35#include <gp_Pnt.hxx>
36#include <gp_Vec.hxx>
37#include <IntSurf.hxx>
38#include <IntSurf_InteriorPoint.hxx>
39#include <IntSurf_SequenceOfPathPoint.hxx>
40#include <math_FunctionSetRoot.hxx>
41#include <Standard_ConstructionError.hxx>
42#include <Standard_OutOfRange.hxx>
43#include <StdFail_NotDone.hxx>
44#include <TColStd_Array1OfInteger.hxx>
45#include <TopTrans_CurveTransition.hxx>
e2065c2f 46
47#define Tolpetit 1.e-10 // pour dist au carre
48
49#define tole 5.e-6
50
51Contap_Contour::Contap_Contour () :
52done(Standard_False),modeset(Standard_False)
53{}
54
55Contap_Contour::Contap_Contour (const gp_Vec& Direction) :
56
57done(Standard_False),modeset(Standard_True)
58{
59 mySFunc.Set(Direction);
60 myAFunc.Set(Direction);
61}
62
63
64Contap_Contour::Contap_Contour (const gp_Vec& Direction,
65 const Standard_Real Angle) :
66
67done(Standard_False),modeset(Standard_True)
68{
69 mySFunc.Set(Direction,Angle);
70 myAFunc.Set(Direction,Angle);
71}
72
73Contap_Contour::Contap_Contour (const gp_Pnt& Eye) :
74
75done(Standard_False),modeset(Standard_True)
76{
77 mySFunc.Set(Eye);
78 myAFunc.Set(Eye);
79}
80
81
82Contap_Contour::Contap_Contour (const Handle(Adaptor3d_HSurface)& Surf,
83 const Handle(Adaptor3d_TopolTool)& Domain,
84 const gp_Vec& Direction) :
85
86done(Standard_False),modeset(Standard_True)
87{
88 Perform(Surf,Domain,Direction);
89}
90
91
92Contap_Contour::Contap_Contour (const Handle(Adaptor3d_HSurface)& Surf,
93 const Handle(Adaptor3d_TopolTool)& Domain,
94 const gp_Vec& Direction,
95 const Standard_Real Angle) :
96
97done(Standard_False),modeset(Standard_True)
98{
99 Perform(Surf,Domain,Direction,Angle);
100}
101
102
103Contap_Contour::Contap_Contour (const Handle(Adaptor3d_HSurface)& Surf,
104 const Handle(Adaptor3d_TopolTool)& Domain,
105 const gp_Pnt& Eye) :
106
107done(Standard_False),modeset(Standard_True)
108{
109 Perform(Surf,Domain,Eye);
110}
111
112
113void Contap_Contour::Init (const gp_Vec& Direction)
114
115{
116 done = Standard_False;
117 modeset = Standard_True;
118 mySFunc.Set(Direction);
119 myAFunc.Set(Direction);
120}
121
122
123void Contap_Contour::Init(const gp_Vec& Direction,
124 const Standard_Real Angle)
125{
126 done = Standard_False;
127 modeset = Standard_True;
128 mySFunc.Set(Direction,Angle);
129 myAFunc.Set(Direction,Angle);
130}
131
132void Contap_Contour::Init (const gp_Pnt& Eye)
133{
134 done = Standard_False;
135 modeset = Standard_True;
136 mySFunc.Set(Eye);
137 myAFunc.Set(Eye);
138}
139
140
141void Contap_Contour::Perform (const Handle(Adaptor3d_HSurface)& Surf,
142 const Handle(Adaptor3d_TopolTool)& Domain)
143{
144 if (!modeset) {Standard_ConstructionError::Raise();}
145 mySFunc.Set(Surf);
146 myAFunc.Set(Surf);
147
148 GeomAbs_SurfaceType typS = Adaptor3d_HSurfaceTool::GetType(Surf);
149 switch (typS) {
150 case GeomAbs_Plane:
151 case GeomAbs_Sphere:
152 case GeomAbs_Cylinder:
153 case GeomAbs_Cone:
154 {
155 PerformAna(Domain); //Surf,Domain,Direction,0.,gp_Pnt(0.,0.,0.),1);
156 }
157 break;
158
159 default:
160 {
161 Perform(Domain); //Surf,Domain,Direction,0.,gp_Pnt(0.,0.,0.),1);
162 }
163 break;
164 }
165
166}
167
168
169void Contap_Contour::Perform (const Handle(Adaptor3d_HSurface)& Surf,
170 const Handle(Adaptor3d_TopolTool)& Domain,
171 const gp_Vec& Direction)
172
173{
174 Init(Direction);
175 Perform(Surf,Domain);
176}
177
178void Contap_Contour::Perform (const Handle(Adaptor3d_HSurface)& Surf,
179 const Handle(Adaptor3d_TopolTool)& Domain,
180 const gp_Vec& Direction,
181 const Standard_Real Angle)
182
183{
184 Init(Direction,Angle);
185 Perform(Surf,Domain);
186}
187
188
189void Contap_Contour::Perform (const Handle(Adaptor3d_HSurface)& Surf,
190 const Handle(Adaptor3d_TopolTool)& Domain,
191 const gp_Pnt& Eye)
192
193{
194 Init(Eye);
195 Perform(Surf,Domain);
196}
197
198static IntSurf_TypeTrans ComputeTransitionOnLine
199(Contap_SurfFunction&,
200 const Standard_Real,
201 const Standard_Real,
202 const gp_Vec&);
203
204
205static IntSurf_TypeTrans ComputeTransitionOngpCircle
206(Contap_SurfFunction&,
207 const gp_Circ&);
208
209
210static IntSurf_TypeTrans ComputeTransitionOngpLine
211(Contap_SurfFunction&,
212 const gp_Lin&);
213
214
215static void ComputeInternalPoints
216(Contap_Line& Line,
217 Contap_SurfFunction&,
218 const Standard_Real ureso,
219 const Standard_Real vreso);
220
221
222static void ComputeInternalPointsOnRstr
223(Contap_Line&,
224 const Standard_Real,
225 const Standard_Real,
226 Contap_SurfFunction&);
227
228static void ProcessSegments (const Contap_TheSearch&,
229 Contap_TheSequenceOfLine&,
230 const Standard_Real,
231 Contap_SurfFunction&,
232 const Handle(Adaptor3d_TopolTool)&);
233
234//-- --------------------------------------------------------------------------------
235//-- Recherche des portions utiles sur les lignes
236
237
238static void Recadre(const Handle(Adaptor3d_HSurface)& myHS1,
239 Standard_Real& u1,
240 Standard_Real& v1) {
241 Standard_Real f,l,lmf;
242 GeomAbs_SurfaceType typs1 = myHS1->GetType();
243
244 Standard_Boolean myHS1IsUPeriodic,myHS1IsVPeriodic;
245 switch (typs1) {
246 case GeomAbs_Cylinder:
247 case GeomAbs_Cone:
248 case GeomAbs_Sphere:
249 {
250 myHS1IsUPeriodic = Standard_True;
251 myHS1IsVPeriodic = Standard_False;
252 break;
253 }
254 case GeomAbs_Torus:
255 {
256 myHS1IsUPeriodic = myHS1IsVPeriodic = Standard_True;
257 break;
258 }
259 default:
260 {
261 myHS1IsUPeriodic = myHS1IsVPeriodic = Standard_False;
262 break;
263 }
264 }
265 if(myHS1IsUPeriodic) {
266 lmf = M_PI+M_PI; //-- myHS1->UPeriod();
267 f = myHS1->FirstUParameter();
268 l = myHS1->LastUParameter();
269 while(u1 < f) { u1+=lmf; }
270 while(u1 > l) { u1-=lmf; }
271 }
272 if(myHS1IsVPeriodic) {
273 lmf = M_PI+M_PI; //-- myHS1->VPeriod();
274 f = myHS1->FirstVParameter();
275 l = myHS1->LastVParameter();
276 while(v1 < f) { v1+=lmf; }
277 while(v1 > l) { v1-=lmf; }
278 }
279}
280
281
282static void LineConstructor(Contap_TheSequenceOfLine& slin,
283 const Handle(Adaptor3d_TopolTool)& Domain,
284 Contap_Line& L,
285 const Handle(Adaptor3d_HSurface)& Surf) {
286
287 //-- ------------------------------------------------------------
288 //-- on decoupe la ligne en portions entre 2 vertex
289 Standard_Real Tol = Precision::PConfusion();
290 Contap_IType typl = L.TypeContour();
291 //-- cout<<"\n ----------- Ligne Constructor "<<endl;
292 if(typl == Contap_Walking) {
293 Standard_Real u1,v1,u2,v2;
294 Standard_Integer nbvtx = L.NbVertex();
295 //-- cout<<" WLine -> "<<nbvtx<<" vtx"<<endl;
296 for(Standard_Integer i=1;i<nbvtx;i++) {
297 Standard_Integer firstp = (Standard_Integer) L.Vertex(i).ParameterOnLine();
298 Standard_Integer lastp = (Standard_Integer) L.Vertex(i+1).ParameterOnLine();
299 if(firstp!=lastp) {
300 Standard_Integer pmid = (firstp+lastp)/2; //-- entiers
301 const IntSurf_PntOn2S& Pmid = L.Point(pmid);
302 Pmid.Parameters(u1,v1,u2,v2);
303 Recadre(Surf,u2,v2);
304 TopAbs_State in2 = Domain->Classify(gp_Pnt2d(u2,v2),Tol);
305 if(in2 == TopAbs_OUT) {
306 }
307 else {
308 //-- cout<<"ContapWLine : firtsp="<<firstp<<" lastp="<<lastp<<" Vtx:"<<i<<","<<i+1<<endl;
309 Handle(IntSurf_LineOn2S) LineOn2S = new IntSurf_LineOn2S();
310 Contap_Line Line;
311 for(Standard_Integer j=firstp; j<=lastp; j++) {
312 LineOn2S->Add(L.Point(j));
313 }
314 Line.SetLineOn2S(LineOn2S);
315 Contap_Point pvtx = L.Vertex(i);
316 pvtx.SetParameter(1);
317 Line.Add(pvtx);
318
319 pvtx = L.Vertex(i+1);
320 pvtx.SetParameter(lastp-firstp+1);
321 Line.Add(pvtx);
322 Line.SetTransitionOnS(L.TransitionOnS());
323 slin.Append(Line);
324 }
325 }
326 }
327 }
328 else if(typl==Contap_Lin) {
329 Standard_Real u2,v2;// u1,v1;
330 Standard_Integer nbvtx = L.NbVertex();
331 //-- cout<<" Lin -> "<<nbvtx<<" vtx"<<endl;
332 for(Standard_Integer i=1;i<nbvtx;i++) {
333 Standard_Real firstp = L.Vertex(i).ParameterOnLine();
334 Standard_Real lastp = L.Vertex(i+1).ParameterOnLine();
335 if(firstp!=lastp) {
336 Standard_Real pmid = (firstp+lastp)*0.5;
337 gp_Pnt Pmid = ElCLib::Value(pmid,L.Line());
338 if(Adaptor3d_HSurfaceTool::GetType(Surf)==GeomAbs_Cylinder) {
339 ElSLib::Parameters(Adaptor3d_HSurfaceTool::Cylinder(Surf),Pmid,u2,v2);
340 }
341 else if(Adaptor3d_HSurfaceTool::GetType(Surf)==GeomAbs_Cone) {
342 ElSLib::Parameters(Adaptor3d_HSurfaceTool::Cone(Surf),Pmid,u2,v2);
343 }
344 else {
345 //-- cout<<" Pb ds Contap_ContourGen_2.gxx (type)"<<endl;
346 }
347
348 Recadre(Surf,u2,v2);
349 TopAbs_State in2 = Domain->Classify(gp_Pnt2d(u2,v2),Tol);
350 if(in2 == TopAbs_OUT) {
351 }
352 else {
353 //-- cout<<"Contap Lin : firtsp="<<firstp<<" lastp="<<lastp<<" Vtx:"<<i<<","<<i+1<<endl;
354 Contap_Line Line;
355 Line.SetValue(L.Line());
356 Contap_Point pvtx = L.Vertex(i);
357 Line.Add(pvtx);
358
359 pvtx = L.Vertex(i+1);
360 Line.Add(pvtx);
361 Line.SetTransitionOnS(L.TransitionOnS());
362 slin.Append(Line);
363 }
364 }
365 }
366 }
367 else if(typl==Contap_Circle) {
368 Standard_Real u2,v2; //u1,v1,
369 Standard_Integer nbvtx = L.NbVertex();
370 //-- cout<<" Circ -> "<<nbvtx<<" vtx"<<endl;
371 Standard_Boolean novtx = Standard_True;
372 if(nbvtx) novtx=Standard_False;
373 for(Standard_Integer i=1;i<nbvtx || novtx;i++) {
374 Standard_Real firstp=0,lastp=M_PI+M_PI;
375 if(novtx == Standard_False) {
376 firstp = L.Vertex(i).ParameterOnLine();
377 lastp = L.Vertex(i+1).ParameterOnLine();
378 }
379 if(Abs(firstp-lastp)>0.000000001) {
380 Standard_Real pmid = (firstp+lastp)*0.5;
381 gp_Pnt Pmid = ElCLib::Value(pmid,L.Circle());
382 if(Adaptor3d_HSurfaceTool::GetType(Surf)==GeomAbs_Cylinder) {
383 ElSLib::Parameters(Adaptor3d_HSurfaceTool::Cylinder(Surf),Pmid,u2,v2);
384 }
385 else if(Adaptor3d_HSurfaceTool::GetType(Surf)==GeomAbs_Cone) {
386 ElSLib::Parameters(Adaptor3d_HSurfaceTool::Cone(Surf),Pmid,u2,v2);
387 }
388 else if(Adaptor3d_HSurfaceTool::GetType(Surf)==GeomAbs_Sphere) {
389 ElSLib::Parameters(Adaptor3d_HSurfaceTool::Sphere(Surf),Pmid,u2,v2);
390 }
391 else {
392 //-- cout<<" Pb ds Contap_ContourGen_2.gxx (typep)"<<endl;
393 }
394
395 Recadre(Surf,u2,v2);
396 TopAbs_State in2 = Domain->Classify(gp_Pnt2d(u2,v2),Tol);
397 if(in2 == TopAbs_OUT) {
398 }
399 else {
400 //-- cout<<"Contap Circle : firtsp="<<firstp<<" lastp="<<lastp<<" Vtx:"<<i<<","<<i+1<<endl;
401 Contap_Line Line;
402 Line.SetValue(L.Circle());
403 if(novtx == Standard_False) {
404 Contap_Point pvtx = L.Vertex(i);
405 Line.Add(pvtx);
406 pvtx = L.Vertex(i+1);
407 Line.Add(pvtx);
408 }
409 Line.SetTransitionOnS(L.TransitionOnS());
410 slin.Append(Line);
411 }
412 }
413 novtx = Standard_False;
414 }
415 if(nbvtx) {
416 Standard_Real firstp = L.Vertex(nbvtx).ParameterOnLine();
417 Standard_Real lastp = L.Vertex(1).ParameterOnLine() + M_PI+M_PI;
418 if(Abs(firstp-lastp)>0.0000000001) {
419 Standard_Real pmid = (firstp+lastp)*0.5;
420 gp_Pnt Pmid = ElCLib::Value(pmid,L.Circle());
421 if(Adaptor3d_HSurfaceTool::GetType(Surf)==GeomAbs_Cylinder) {
422 ElSLib::Parameters(Adaptor3d_HSurfaceTool::Cylinder(Surf),Pmid,u2,v2);
423 }
424 else if(Adaptor3d_HSurfaceTool::GetType(Surf)==GeomAbs_Cone) {
425 ElSLib::Parameters(Adaptor3d_HSurfaceTool::Cone(Surf),Pmid,u2,v2);
426 }
427 else if(Adaptor3d_HSurfaceTool::GetType(Surf)==GeomAbs_Sphere) {
428 ElSLib::Parameters(Adaptor3d_HSurfaceTool::Sphere(Surf),Pmid,u2,v2);
429 }
430 else {
431 //-- cout<<" Pb ds Contap_ContourGen_2.gxx (typep)"<<endl;
432 }
433
434 Recadre(Surf,u2,v2);
435 TopAbs_State in2 = Domain->Classify(gp_Pnt2d(u2,v2),Tol);
436 if(in2 == TopAbs_OUT) {
437 }
438 else {
439 //-- cout<<"Contap Circle *Compl* : firtsp="<<firstp<<" lastp="<<lastp<<" Vtx:"<<i<<","<<i+1<<endl;
440 Contap_Line Line;
441 Line.SetValue(L.Circle());
442 Contap_Point pvtx = L.Vertex(nbvtx);
443 Line.Add(pvtx);
444
445 pvtx = L.Vertex(1); pvtx.SetParameter(pvtx.ParameterOnLine()+M_PI+M_PI);
446 Line.Add(pvtx);
447 Line.SetTransitionOnS(L.TransitionOnS());
448 slin.Append(Line);
449 }
450 }
451 }
452 }
453 else {
454 //-- cout<<" ni WLine ni Lin ni Circ "<<endl;
455 slin.Append(L);
456 }
457 //--
458}
459
460//-- --------------------------------------------------------------------------------
461
462
463
464static void KeepInsidePoints(const Contap_TheSearchInside& solins,
465 const Contap_TheSearch& solrst,
466 Contap_SurfFunction& Func,
467 IntSurf_SequenceOfInteriorPoint& seqpins)
468
469{
470 Standard_Integer Nba = solrst.NbSegments();
e2065c2f 471 Standard_Integer Nbp,indp,inda;
472 Standard_Real U,V,paramproj;
473 gp_Pnt2d toproj,Ptproj;
474 Standard_Boolean projok,tokeep;
475 const Handle(Adaptor3d_HSurface)& Surf = Func.Surface();
476
477 Nbp = solins.NbPoints();
478 for (indp=1; indp <= Nbp; indp++) {
479 tokeep = Standard_True;
480 const IntSurf_InteriorPoint& pti = solins.Value(indp);
481 pti.Parameters(U,V);
482 toproj = gp_Pnt2d(U,V);
483 for (inda = 1; inda <= Nba; inda++) {
484 const Handle(Adaptor2d_HCurve2d)& thearc = solrst.Segment(inda).Curve();
485 projok = Contap_HContTool::Project(thearc,toproj,paramproj,Ptproj);
486 if (projok) {
487 gp_Pnt pprojete = Adaptor3d_HSurfaceTool::Value(Surf,Ptproj.X(),Ptproj.Y());
488 if (pti.Value().Distance(pprojete) <= Precision::Confusion()) {
489 tokeep = Standard_False;
490 break;
491 }
492 }
493 }
494 if (tokeep) {
495 seqpins.Append(pti);
496 }
497 }
498}
499
500
501static void ComputeTangency (const Contap_TheSearch& solrst,
502 const Handle(Adaptor3d_TopolTool)& Domain,
503 Contap_SurfFunction& Func,
504 IntSurf_SequenceOfPathPoint& seqpdep,
505 TColStd_Array1OfInteger& Destination)
506{
507
508 Standard_Integer i,k;
509 Standard_Integer NbPoints = solrst.NbPoints();
510 Standard_Integer seqlength = 0;
511
512 Standard_Real theparam,test;
513 Standard_Boolean fairpt;
514 TopAbs_Orientation arcorien,vtxorien;
515 Standard_Boolean ispassing;
516
517 math_Vector X(1, 2);
518 math_Vector F(1, 1);
519 math_Matrix D(1, 1, 1, 2);
520
521 gp_Vec normale, vectg, tg3drst,v1,v2;
522 gp_Dir2d dirtg;
523 gp_Vec2d tg2drst;
524 gp_Pnt2d pt2d;
525
526 IntSurf_PathPoint PPoint;
527 const Handle(Adaptor3d_HSurface)& Surf = Func.Surface();
528
529 for (i=1; i<= NbPoints; i++) {
530
531 if (Destination(i) == 0) {
532
533 const Contap_ThePathPointOfTheSearch& PStart = solrst.Point(i);
534 const Handle(Adaptor2d_HCurve2d)& thearc = PStart.Arc();
535 theparam = PStart.Parameter();
536 gp_Pnt2d Ptoproj=Contap_HCurve2dTool::Value(thearc,theparam);
537 //-- lbr le 15 mai 97
538 //-- On elimine les points qui sont egalement present sur une restriction solution
539 Standard_Boolean SurUneRestrictionSolution = Standard_False;
540 for(Standard_Integer restriction=1;
541 SurUneRestrictionSolution==Standard_False && restriction<=solrst.NbSegments();
542 restriction++) {
543 const Handle(Adaptor2d_HCurve2d)& thearcsol = solrst.Segment(restriction).Curve();
544 Standard_Real paramproj;
545 gp_Pnt2d pproj;
546 Standard_Boolean projok = Contap_HContTool::Project(thearcsol,Ptoproj,paramproj,pproj);
547 if(projok) {
548 //gp_Pnt pprojete = Adaptor3d_HSurfaceTool::Value(Surf,Ptoproj.X(),Ptoproj.Y());
549 //IFV - begin
550 gp_Pnt pprojete = Adaptor3d_HSurfaceTool::Value(Surf,pproj.X(),pproj.Y());
551 //IFV - end
552 if ((PStart.Value()).Distance(pprojete) <= Precision::Confusion()) {
553 SurUneRestrictionSolution = Standard_True;
554 }
555 }
556 }
557 if(SurUneRestrictionSolution == Standard_False) {
558 arcorien = Domain->Orientation(thearc);
559 ispassing = (arcorien == TopAbs_INTERNAL ||
560 arcorien == TopAbs_EXTERNAL);
561
562 Contap_HCurve2dTool::D1(thearc,theparam,pt2d,tg2drst);
563 X(1) = pt2d.X();
564 X(2) = pt2d.Y();
565 PPoint.SetValue(PStart.Value(),X(1),X(2));
566
567 Func.Values(X,F,D);
568 if (Func.IsTangent()) {
569 PPoint.SetTangency(Standard_True);
570 Destination(i) = seqlength+1;
571 if (!PStart.IsNew()) {
572 const Handle(Adaptor3d_HVertex)& vtx = PStart.Vertex();
573 for (k=i+1; k<=NbPoints; k++) {
574 if (Destination(k) ==0) {
575 const Contap_ThePathPointOfTheSearch& PStart2 = solrst.Point(k);
576 if (!PStart2.IsNew()) {
577 const Handle(Adaptor3d_HVertex)& vtx2 = PStart2.Vertex();
578 if (Domain->Identical(vtx,vtx2)) {
579 const Handle(Adaptor2d_HCurve2d)& thearc2 = PStart2.Arc();
580 theparam = PStart2.Parameter();
581 arcorien = Domain->Orientation(thearc2);
582 ispassing = ispassing && (arcorien == TopAbs_INTERNAL ||
583 arcorien == TopAbs_EXTERNAL);
584
585 pt2d = Contap_HCurve2dTool::Value(thearc2,theparam);
586 X(1) = pt2d.X();
587 X(2) = pt2d.Y();
588 PPoint.AddUV(X(1),X(2));
589 Destination(k) = seqlength+1;
590 }
591 }
592 }
593 }
594 }
595 PPoint.SetPassing(ispassing);
596 seqpdep.Append(PPoint);
597 seqlength++;
598 }
599 else { // on a un point de depart potentiel
600
601 vectg = Func.Direction3d();
602 dirtg = Func.Direction2d();
603
604 gp_Pnt ptbid;
605 // Adaptor3d_HSurfaceTool::D1(Surf,X(1),X(2),ptbid,v1,v2);
606 Contap_SurfProps::DerivAndNorm(Surf,X(1),X(2),ptbid,v1,v2,normale);
607 tg3drst = tg2drst.X()*v1 + tg2drst.Y()*v2;
608 // normale = v1.Crossed(v2);
609 if(normale.SquareMagnitude() < RealEpsilon()) {
610 //-- cout<<"\n*** Contap_ContourGen_2.gxx Normale Nulle en U:"<<X(1)<<" V:"<<X(2)<<endl;
611 }
612 else {
613 test = vectg.Dot(normale.Crossed(tg3drst));
614
615 if (PStart.IsNew()) {
616 Standard_Real tbis = vectg.Normalized().Dot(tg3drst.Normalized());
617 if (Abs(tbis) < 1.-tole) {
618
619 if ((test < 0. && arcorien == TopAbs_FORWARD) ||
620 (test > 0. && arcorien == TopAbs_REVERSED)) {
621 vectg.Reverse();
622 dirtg.Reverse();
623 }
624 PPoint.SetDirections(vectg,dirtg);
625 }
626 else { // on garde le point comme point d`arret (tangent)
627 PPoint.SetTangency(Standard_True);
628 }
629 PPoint.SetPassing(ispassing);
630 Destination(i) = seqlength+1;
631 seqpdep.Append(PPoint);
632 seqlength++;
633 }
634 else { // traiter la transition complexe
635 gp_Dir bidnorm(1.,1.,1.);
636
637 Standard_Boolean tobeverified = Standard_False;
638 TopAbs_Orientation LocTrans;
639 TopTrans_CurveTransition comptrans;
640 comptrans.Reset(vectg,bidnorm,0.);
641 if (arcorien != TopAbs_INTERNAL &&
642 arcorien != TopAbs_EXTERNAL) {
643 // pour essai
644 const Handle(Adaptor3d_HVertex)& vtx = PStart.Vertex();
645 vtxorien = Domain->Orientation(vtx);
646 test = test/(vectg.Magnitude());
647 test = test/((normale.Crossed(tg3drst)).Magnitude());
648
649 if (Abs(test) <= tole) {
650 tobeverified = Standard_True;
651 LocTrans = TopAbs_EXTERNAL; // et pourquoi pas INTERNAL
652 }
653 else {
654 if ((test > 0. && arcorien == TopAbs_FORWARD) ||
655 (test < 0. && arcorien == TopAbs_REVERSED)){
656 LocTrans = TopAbs_FORWARD;
657 }
658 else {
659 LocTrans = TopAbs_REVERSED;
660 }
661 if (arcorien == TopAbs_REVERSED) {tg3drst.Reverse();} // pas deja fait ???
662 }
663
664 comptrans.Compare(tole,tg3drst,bidnorm,0.,LocTrans,vtxorien);
665 }
666 Destination(i) = seqlength+1;
667 for (k= i+1; k<=NbPoints; k++) {
668 if (Destination(k) == 0) {
669 const Contap_ThePathPointOfTheSearch& PStart2 = solrst.Point(k);
670 if (!PStart2.IsNew()) {
671 const Handle(Adaptor3d_HVertex)& vtx2 = PStart2.Vertex();
672 if (Domain->Identical(PStart.Vertex(),vtx2)) {
673 const Handle(Adaptor2d_HCurve2d)& thearc2 = PStart2.Arc();
674 theparam = PStart2.Parameter();
675 arcorien = Domain->Orientation(thearc2);
676
677 Contap_HCurve2dTool::D1(thearc2,theparam,pt2d,tg2drst);
678 X(1) = pt2d.X();
679 X(2) = pt2d.Y();
680 PPoint.AddUV(X(1),X(2));
681
682 if (arcorien != TopAbs_INTERNAL &&
683 arcorien != TopAbs_EXTERNAL) {
684 ispassing = Standard_False;
685 tg3drst = tg2drst.X()*v1 + tg2drst.Y()*v2;
686 test = vectg.Dot(normale.Crossed(tg3drst));
687 test = test/(vectg.Magnitude());
688 test = test /((normale.Crossed(tg3drst)).Magnitude());
689
690 vtxorien = Domain->Orientation(vtx2);
691 if (Abs(test) <= tole) {
692 tobeverified = Standard_True;
693 LocTrans = TopAbs_EXTERNAL; // et pourquoi pas INTERNAL
694 }
695 else {
696 if ((test > 0. && arcorien == TopAbs_FORWARD) ||
697 (test < 0. && arcorien == TopAbs_REVERSED)){
698 LocTrans = TopAbs_FORWARD;
699 }
700 else {
701 LocTrans = TopAbs_REVERSED;
702 }
703 if (arcorien == TopAbs_REVERSED) {tg3drst.Reverse();} //deja fait????
704 }
705
706 comptrans.Compare(tole,tg3drst,bidnorm,0.,LocTrans,vtxorien);
707 }
708 Destination(k) = seqlength+1;
709 }
710 }
711 }
712 }
713 fairpt = Standard_True;
714 if (!ispassing) {
715 TopAbs_State Before = comptrans.StateBefore();
716 TopAbs_State After = comptrans.StateAfter();
717 if ((Before == TopAbs_UNKNOWN)||(After == TopAbs_UNKNOWN)) {
718 fairpt = Standard_False;
719 }
720 else if (Before == TopAbs_IN) {
721 if (After == TopAbs_IN) {
722 ispassing = Standard_True;
723 }
724 else {
725 vectg.Reverse();
726 dirtg.Reverse();
727 }
728 }
729 else {
730 if (After !=TopAbs_IN) {
731 fairpt = Standard_False;
732 }
733 }
734 }
735
736 // evite de partir le long d une restriction solution
737
738 if (fairpt && tobeverified) {
739 for (k=i; k <=NbPoints ; k++) {
740 if (Destination(k)==seqlength + 1) {
741 theparam = solrst.Point(k).Parameter();
742 const Handle(Adaptor2d_HCurve2d)& thearc2 = solrst.Point(k).Arc();
743 arcorien = Domain->Orientation(thearc2);
744
745 if (arcorien == TopAbs_FORWARD ||
746 arcorien == TopAbs_REVERSED) {
747 Contap_HCurve2dTool::D1(thearc2,theparam,pt2d,tg2drst);
748 tg3drst = tg2drst.X()*v1 + tg2drst.Y()*v2;
749 vtxorien = Domain->Orientation(solrst.Point(k).Vertex());
750 if ((arcorien == TopAbs_FORWARD &&
751 vtxorien == TopAbs_REVERSED) ||
752 (arcorien == TopAbs_REVERSED &&
753 vtxorien == TopAbs_FORWARD)) {
754 tg3drst.Reverse();
755 }
756 test = vectg.Normalized().Dot(tg3drst.Normalized());
757 if (test >= 1. - tole) {
758 fairpt = Standard_False;
759 break;
760 }
761 }
762 }
763 }
764 }
765
766 if (fairpt) {
767 PPoint.SetDirections(vectg,dirtg);
768 PPoint.SetPassing(ispassing);
769 seqpdep.Append(PPoint);
770 seqlength++;
771 }
772 else { // il faut remettre en "ordre" si on ne garde pas le point.
773 for (k=i; k <=NbPoints ; k++) {
774 if (Destination(k)==seqlength + 1) {
775 Destination(k) = -Destination(k);
776 }
777 }
778 }
779 }
780 }
781 }
782 }
783 }
784 }
785}
786
787
788IntSurf_TypeTrans ComputeTransitionOnLine(Contap_SurfFunction& SFunc,
789 const Standard_Real u,
790 const Standard_Real v,
791 const gp_Vec& tgline)
792{
793 gp_Vec d1u,d1v;
794 gp_Pnt pntbid;
795 //gp_Vec tglineuv;
796
797 Adaptor3d_HSurfaceTool::D1(SFunc.Surface(),u,v,pntbid,d1u,d1v);
798
799 //------------------------------------------------------
800 //-- Calcul de la tangente dans l espace uv ---
801 //------------------------------------------------------
802
803 Standard_Real det,d1uT,d1vT,normu2,normv2,d1ud1v,alpha,beta;
804 d1uT = d1u.Dot(tgline);
805 d1vT = d1v.Dot(tgline);
806 normu2 = d1u.Dot(d1u);
807 normv2 = d1v.Dot(d1v);
808 d1ud1v = d1u.Dot(d1v);
809 det = normu2 * normv2 - d1ud1v * d1ud1v;
810 if(det<RealEpsilon()) {
811 //-- On ne doit pas passer ici !!
812 //-- cout<<" Probleme !!!"<<endl ;
813 return IntSurf_Undecided;
814 }
815
816 alpha = (d1uT * normv2 - d1vT * d1ud1v)/det;
817 beta = (normu2 * d1vT - d1ud1v * d1uT)/det;
818 //-----------------------------------------------------
819 //-- Calcul du Gradient de la fonction Utilisee --
820 //-- pour le contour apparent --
821 //-----------------------------------------------------
822
823 Standard_Real v1,v2;
824 math_Vector X(1,2);
825 math_Matrix Df(1,1,1,2);
826 X(1) = u;
827 X(2) = v;
828 SFunc.Derivatives(X,Df);
829 v1 = Df(1,1);
830 v2 = Df(1,2);
831
832 //-----------------------------------------------------
833 //-- On calcule si la fonction --
834 //-- F(.) = Normale . Dir_Regard --
835 //-- Croit Losrque l on se deplace sur la Gauche --
836 //-- de la direction de deplacement sur la ligne. --
837 //-----------------------------------------------------
838
839 det = -v1*beta + v2*alpha;
840
841 if(det<RealEpsilon()) { // revoir le test jag 940620
842 return IntSurf_Undecided;
843 }
844 if(det>0.0) {
845 return(IntSurf_Out);
846 }
847 return(IntSurf_In);
848}
849
850
851void ProcessSegments (const Contap_TheSearch& solrst,
852 Contap_TheSequenceOfLine& slin,
853 const Standard_Real TolArc,
854 Contap_SurfFunction& SFunc,
855 const Handle(Adaptor3d_TopolTool)& Domain)
856
857{
858 Standard_Integer i,j,k;
859 Standard_Integer nbedg = solrst.NbSegments();
860 Standard_Integer Nblines,Nbpts;
861
862 Handle(Adaptor2d_HCurve2d) arcRef;
863 Contap_Point ptvtx;
864
865 Contap_ThePathPointOfTheSearch PStartf,PStartl;
866
867 Standard_Boolean dofirst,dolast,procf,procl;
868 Standard_Real paramf =0.,paraml =0.,U;
869 Contap_Line theline;
870
871 gp_Vec tgline;//,norm1,norm2;
872 gp_Pnt valpt;
873
874 gp_Vec d1u,d1v;
875 gp_Pnt2d p2d;
876 gp_Vec2d d2d;
877
878
879 for (i = 1; i <= nbedg; i++) {
880
881 const Contap_TheSegmentOfTheSearch& thesegsol = solrst.Segment(i);
882 theline.SetValue(thesegsol.Curve());
883
884 // Traitement des points debut/fin du segment solution.
885
886 dofirst = Standard_False;
887 dolast = Standard_False;
888 procf = Standard_False;
889 procl = Standard_False;
890
891 if (thesegsol.HasFirstPoint()) {
892 dofirst = Standard_True;
893 PStartf = thesegsol.FirstPoint();
894 paramf = PStartf.Parameter();
895 }
896 if (thesegsol.HasLastPoint()) {
897 dolast = Standard_True;
898 PStartl = thesegsol.LastPoint();
899 paraml = PStartl.Parameter();
900 }
901
902 // determination de la transition
903 if (dofirst && dolast) {
904 U = (paramf+paraml)/2.;
905 }
906 else if (dofirst) {
907 U = paramf + 1.0;
908 }
909 else if (dolast) {
910 U = paraml - 1.0;
911 }
912 else {
913 U = 0.0;
914 }
915
916 Contap_HCurve2dTool::D1(thesegsol.Curve(),U,p2d,d2d);
917 Adaptor3d_HSurfaceTool::D1(SFunc.Surface(),p2d.X(),p2d.Y(),valpt,d1u,d1v);
918 tgline.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
919 IntSurf_TypeTrans tral =
920 ComputeTransitionOnLine(SFunc,p2d.X(),p2d.Y(),tgline);
921
922 theline.SetTransitionOnS(tral);
923
924
925 if (dofirst || dolast) {
926 Nblines = slin.Length();
927 for (j=1; j<=Nblines; j++) {
928 Nbpts = slin(j).NbVertex();
929 for (k=1; k<=Nbpts;k++) {
930 ptvtx = slin(j).Vertex(k);
931 if (dofirst) {
932 if (ptvtx.Value().Distance(PStartf.Value()) <=TolArc) {
933 slin(j).Vertex(k).SetMultiple();
934 ptvtx.SetMultiple();
935 ptvtx.SetParameter(paramf);
936 theline.Add(ptvtx);
937 procf=Standard_True;
938 }
939 }
940 if (dolast) {
941 if (ptvtx.Value().Distance(PStartl.Value()) <=TolArc) {
942 slin(j).Vertex(k).SetMultiple();
943 ptvtx.SetMultiple();
944 ptvtx.SetParameter(paraml);
945 theline.Add(ptvtx);
946 procl=Standard_True;
947 }
948 }
949 }
950 // Si on a traite le pt debut et/ou fin, on ne doit pas recommencer si
951 // il (ils) correspond(ent) a un point multiple.
952
953 if (procf) {
954 dofirst = Standard_False;
955 }
956 if (procl) {
957 dolast = Standard_False;
958 }
959 }
960 }
961
962 // Si on n a pas trouve le point debut et./ou fin sur une des lignes
963 // d intersection, il faut quand-meme le placer sur la restriction solution
964
965 if (dofirst) {
966
967 p2d = Contap_HCurve2dTool::Value(thesegsol.Curve(),paramf);
968 ptvtx.SetValue(PStartf.Value(),p2d.X(),p2d.Y());
969 ptvtx.SetParameter(paramf);
970 if (! PStartf.IsNew()) {
971 ptvtx.SetVertex(PStartf.Vertex());
972 }
973 theline.Add(ptvtx);
974 }
975 if (dolast) {
976 p2d = Contap_HCurve2dTool::Value(thesegsol.Curve(),paraml);
977 ptvtx.SetValue(PStartl.Value(),p2d.X(),p2d.Y());
978 ptvtx.SetParameter(paraml);
979 if (! PStartl.IsNew()) {
980 ptvtx.SetVertex(PStartl.Vertex());
981 }
982 theline.Add(ptvtx);
983 }
984
985 // il faut chercher le points internal sur les restrictions solutions.
986 if (thesegsol.HasFirstPoint() && thesegsol.HasLastPoint()) {
987 ComputeInternalPointsOnRstr(theline,paramf,paraml,SFunc);
988 }
989 LineConstructor(slin,Domain,theline,SFunc.Surface()); //-- lbr
990 //-- slin.Append(theline);
991 theline.Clear();
992 }
993}
994
995void ComputeInternalPointsOnRstr
996(Contap_Line& Line,
997 const Standard_Real Paramf,
998 const Standard_Real Paraml,
999 Contap_SurfFunction& SFunc)
1000{
1001 // On recherche les points ou la tangente a la ligne de contour et
1002 // la direction sont alignees.
1003 // 1ere etape : recherche de changement de signe.
1004 // 2eme etape : localisation de la solution par dichotomie
1005
1006
1007 Standard_Integer indexinf,indexsup,i;
1008 gp_Vec tgt, vecref, vectest, vtestb, vecregard,d1u,d1v;
1009 gp_Pnt pcour;
1010 gp_Pnt2d p2d;
1011 gp_Vec2d d2d;
1012 Standard_Boolean found,ok = Standard_False,toutvu,solution;
1013 Standard_Real paramp = 0.,paraminf,paramsup,toler;
1014
1015 if (Line.TypeContour() != Contap_Restriction) {
1016 return;
1017 }
1018
857ffd5e 1019 const Handle(Adaptor2d_HCurve2d)& thearc = Line.Arc();
e2065c2f 1020
1021 const Handle(Adaptor3d_HSurface)& Surf = SFunc.Surface();
1022 Contap_TFunction TypeFunc(SFunc.FunctionType());
1023
1024 Standard_Integer Nbpnts = Contap_HContTool::NbSamplesOnArc(thearc);
1025 indexinf = 1;
1026 vecregard = SFunc.Direction();
1027 toler = Contap_HCurve2dTool::Resolution(thearc,Precision::Confusion());
1028 found = Standard_False;
1029
1030 do {
1031 paraminf = ((Nbpnts-indexinf)*Paramf + (indexinf-1)*Paraml)/(Nbpnts-1);
1032 Contap_HCurve2dTool::D1(thearc,paraminf,p2d,d2d);
1033 Adaptor3d_HSurfaceTool::D1(Surf,p2d.X(),p2d.Y(),pcour,d1u,d1v);
1034 tgt.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1035
1036 if (tgt.Magnitude() > gp::Resolution()) {
1037 if (TypeFunc == Contap_ContourPrs || TypeFunc==Contap_DraftPrs) {
1038 vecregard.SetXYZ(pcour.XYZ()-SFunc.Eye().XYZ());
1039 }
1040 vecref = vecregard.Crossed(tgt);
1041
1042 if (vecref.Magnitude() <= gp::Resolution()) {
1043 indexinf++;
1044 }
1045 else {
1046 found = Standard_True;
1047 }
1048 }
1049 else {
1050 indexinf++;
1051 }
1052 } while ((indexinf <= Nbpnts) && (!found));
1053
1054
1055 indexsup = indexinf +1;
1056 toutvu = (indexsup > Nbpnts);
1057 while (!toutvu) {
1058 paramsup = ((Nbpnts-indexsup)*Paramf + (indexsup-1)*Paraml)/(Nbpnts-1);
1059 Contap_HCurve2dTool::D1(thearc,paramsup,p2d,d2d);
1060 Adaptor3d_HSurfaceTool::D1(Surf,p2d.X(),p2d.Y(),pcour,d1u,d1v);
1061 tgt.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1062
1063 if (tgt.Magnitude() > gp::Resolution()) {
1064 if (TypeFunc == Contap_ContourPrs || TypeFunc==Contap_DraftPrs) {
1065 vecregard.SetXYZ(pcour.XYZ()-SFunc.Eye().XYZ());
1066 }
1067 vectest = vecregard.Crossed(tgt);
1068 }
1069 else {
1070 vectest = gp_Vec(0.,0.,0.);
1071 }
1072 if (vectest.Magnitude() <= gp::Resolution()) {
1073 // On cherche un vrai changement de signe
1074 indexsup++;
1075 }
1076 else {
1077 if (vectest.Dot(vecref) < 0.) {
1078 // Essayer de converger
1079 // cout << "Changement de signe detecte" << endl;
1080 solution = Standard_False;
1081 while (!solution) {
1082 paramp = (paraminf+paramsup)/2.;
1083 Contap_HCurve2dTool::D1(thearc,paramp,p2d,d2d);
1084 Adaptor3d_HSurfaceTool::D1(Surf,p2d.X(),p2d.Y(),pcour,d1u,d1v);
1085 tgt.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1086
1087 if (tgt.Magnitude() > gp::Resolution()) {
1088 if (TypeFunc == Contap_ContourPrs || TypeFunc==Contap_DraftPrs) {
1089 vecregard.SetXYZ(pcour.XYZ()-SFunc.Eye().XYZ());
1090 }
1091 vtestb = vecregard.Crossed(tgt);
1092 }
1093 else {
1094 vtestb = gp_Vec(0.,0.,0.);
1095 }
1096
1097 if ((vtestb.Magnitude() <= gp::Resolution())||
1098 (Abs(paramp-paraminf) <= toler) ||
1099 (Abs(paramp-paramsup) <= toler)) {
1100 // on est a la solution
1101 solution = Standard_True;
1102 ok = Standard_True;
1103 }
1104 else if (vtestb.Dot(vecref) < 0.) {
1105 paramsup = paramp;
1106 }
1107 else {
1108 paraminf = paramp;
1109 }
1110
1111 }
1112
1113 if (ok) {
1114 // On verifie que le point trouve ne correspond pas a un ou des
1115 // vertex deja existant(s). On teste sur le parametre paramp.
1116 for (i=1; i<=Line.NbVertex(); i++) {
1117 Contap_Point& thevtx = Line.Vertex(i);
1118 if (Abs(thevtx.ParameterOnLine()-paramp) <= toler) {
1119 thevtx.SetInternal();
1120 ok = Standard_False; // on a correspondance
1121 }
1122 }
1123 if (ok) { // il faut alors rajouter le point
1124 Contap_Point internalp(pcour,p2d.X(),p2d.Y());
1125 internalp.SetParameter(paramp);
1126 internalp.SetInternal();
1127 Line.Add(internalp);
1128 }
1129 }
1130 paramsup = ((Nbpnts-indexsup)*Paramf + (indexsup-1)*Paraml)/(Nbpnts-1);
1131 }
1132 vecref = vectest;
1133 indexinf = indexsup;
1134 indexsup++;
1135 paraminf = paramsup;
1136 }
1137 toutvu = (indexsup > Nbpnts);
1138 }
1139}
1140
1141
1142void ComputeInternalPoints
1143(Contap_Line& Line,
1144 Contap_SurfFunction& SFunc,
1145 const Standard_Real ureso,
1146 const Standard_Real vreso)
1147
1148{
1149 // On recherche les points ou la tangente a la ligne de contour et
1150 // la direction sont alignees.
1151 // 1ere etape : recheche de changement de signe.
1152 // 2eme etape : localisation de la solution par simili dichotomie
1153
1154
1155 Standard_Integer indexinf,indexsup,index;
1156 gp_Vec tgt, vecref, vectest, vtestb, vecregard;
1157 //gp_Pnt pprec,pcour;
1158 Standard_Boolean found,ok = Standard_False,toutvu,solution;
1159 Standard_Real paramp = 0.,U,V;
1160
1161 math_Vector XInf(1,2),XSup(1,2),X(1,2),F(1,1);
1162 math_Matrix DF(1,1,1,2);
1163 math_Vector toler(1,2),infb(1,2),supb(1,2);
1164
1165 if (Line.TypeContour() != Contap_Walking) {
1166 return;
1167 }
1168
1169 Standard_Integer Nbpnts = Line.NbPnts();
1170 const Handle(Adaptor3d_HSurface)& Surf = SFunc.Surface();
1171 Contap_TFunction TypeFunc(SFunc.FunctionType());
1172
1173 toler(1) = ureso; //-- Trop long !!! Adaptor3d_HSurfaceTool::UResolution(Surf,SFunc.Tolerance());
1174 toler(2) = vreso; //---Beaucoup trop long !!! Adaptor3d_HSurfaceTool::VResolution(Surf,SFunc.Tolerance());
1175 infb(1) = Adaptor3d_HSurfaceTool::FirstUParameter(Surf);
1176 infb(2) = Adaptor3d_HSurfaceTool::FirstVParameter(Surf);
1177 supb(1) = Adaptor3d_HSurfaceTool::LastUParameter(Surf);
1178 supb(2) = Adaptor3d_HSurfaceTool::LastVParameter(Surf);
1179
1180 math_FunctionSetRoot rsnld(SFunc,toler,30);
1181
1182 indexinf = 1;
1183 vecregard = SFunc.Direction();
1184
1185 found = Standard_False;
1186 do {
1187 Line.Point(indexinf).ParametersOnS2(XInf(1),XInf(2));
1188 SFunc.Values(XInf,F,DF);
1189 if (!SFunc.IsTangent()) {
1190 tgt = SFunc.Direction3d();
1191 if (TypeFunc == Contap_ContourPrs || TypeFunc == Contap_DraftPrs) {
1192 vecregard.SetXYZ(Line.Point(indexinf).Value().XYZ()-SFunc.Eye().XYZ());
1193 }
1194 vecref = vecregard.Crossed(tgt);
1195
1196 if (vecref.Magnitude() <= gp::Resolution()) {
1197 indexinf++;
1198 }
1199 else {
1200 found = Standard_True;
1201 }
1202 }
1203 else {
1204 indexinf++;
1205 }
1206 } while ((indexinf <= Nbpnts) && (!found));
1207
1208
1209 indexsup = indexinf +1;
1210 toutvu = (indexsup > Nbpnts);
1211 while (!toutvu) {
1212 Line.Point(indexsup).ParametersOnS2(XSup(1),XSup(2));
1213 SFunc.Values(XSup,F,DF);
1214 if (!SFunc.IsTangent()) {
1215 tgt = SFunc.Direction3d();
1216
1217 if (TypeFunc == Contap_ContourPrs || TypeFunc == Contap_DraftPrs) {
1218 vecregard.SetXYZ(Line.Point(indexsup).Value().XYZ()-SFunc.Eye().XYZ());
1219 }
1220 vectest = vecregard.Crossed(tgt);
1221 }
1222 else {
1223 vectest = gp_Vec(0.,0.,0.);
1224 }
1225 if (vectest.Magnitude() <= gp::Resolution()) {
1226 // On cherche un vrai changement de signe
1227 indexsup++;
1228 }
1229 else {
1230 if (vectest.Dot(vecref) < 0.) {
1231 // Essayer de converger
1232 // cout << "Changement de signe detecte" << endl;
1233 solution = Standard_False;
1234 while (!solution) {
1235 X(1) = (XInf(1) + XSup(1)) /2.;
1236 X(2) = (XInf(2) + XSup(2)) /2.;
1237 rsnld.Perform(SFunc,X,infb,supb);
1238
1239 if (!rsnld.IsDone()) {
1240 cout << "Echec recherche internal points" << endl;
1241 solution = Standard_True;
1242 ok = Standard_False;
1243 }
1244 else {
1245
1246 rsnld.Root(X);
1247 SFunc.Values(X,F,DF);
1248 if (Abs(F(1)) <= SFunc.Tolerance()) {
1249
1250 if (!SFunc.IsTangent()) {
1251 tgt = SFunc.Direction3d();
1252 if (TypeFunc == Contap_ContourPrs ||
1253 TypeFunc == Contap_DraftPrs) {
1254 vecregard.SetXYZ(SFunc.Point().XYZ()-SFunc.Eye().XYZ());
1255 }
1256 vtestb = vecregard.Crossed(tgt);
1257 }
1258 else {
1259 vtestb = gp_Vec(0.,0.,0.);
1260 }
1261 if ((vtestb.Magnitude() <= gp::Resolution())||
1262 (Abs(X(1)-XInf(1)) <= toler(1)
1263 && Abs(X(2)-XInf(2)) <= toler(2)) ||
1264 (Abs(X(1)-XSup(1)) <= toler(1)
1265 && Abs(X(2)-XSup(2)) <= toler(2))) {
1266 // on est a la solution
1267 solution = Standard_True;
1268 ok = Standard_True;
1269 }
1270 else if (vtestb.Dot(vecref) < 0.) {
1271 XSup = X;
1272 }
1273 else {
1274 XInf = X;
1275 }
1276 }
1277 else { // on n est pas sur une solution
1278 cout << "Echec recherche internal points" << endl;
1279 solution = Standard_True;
1280 ok = Standard_False;
1281 }
1282 }
1283 }
1284
1285 if (ok) {
1286 Standard_Boolean newpoint = Standard_False;
1287 Line.Point(indexinf).ParametersOnS2(U,V);
1288 gp_Vec2d vinf(X(1)-U,X(2)-V);
1289 if (Abs(vinf.X()) <= toler(1) && Abs(vinf.Y()) <= toler(2)) {
1290 paramp = indexinf;
1291 }
1292 else {
1293 for (index = indexinf+1; index <= indexsup; index++) {
1294 Line.Point(index).ParametersOnS2(U,V);
1295 gp_Vec2d vsup(X(1)-U,X(2)-V);
1296 if (Abs(vsup.X()) <= toler(1) && Abs(vsup.Y()) <= toler(2)) {
1297 paramp = index;
1298 break;
1299 }
1300 else if (vinf.Dot(vsup) < 0.) {
1301 // on est entre les 2 points
1302 paramp = index;
1303 IntSurf_PntOn2S pt2s;
1304 pt2s.SetValue(SFunc.Point(),Standard_False,X(1),X(2));
1305 Line.LineOn2S()->InsertBefore(index,pt2s);
1306
1307 //-- Il faut decaler les parametres des vertex situes entre
1308 //-- index et NbPnts ###################################
1309 for(Standard_Integer v=1; v<=Line.NbVertex(); v++) {
1310 Contap_Point& Vertex = Line.Vertex(v);
1311 if(Vertex.ParameterOnLine() >= index) {
1312 Vertex.SetParameter(Vertex.ParameterOnLine()+1);
1313 }
1314 }
1315
1316 Nbpnts = Nbpnts+1;
1317 indexsup = indexsup+1;
1318 newpoint = Standard_True;
1319 break;
1320 }
1321 else {
1322 vinf = vsup;
1323 }
1324 }
1325 }
1326
1327 Standard_Integer v;
1328 if (!newpoint) {
1329 // on est sur un point de cheminement. On regarde alors
1330 // la correspondance avec un vertex existant.
1331 newpoint = Standard_True;
1332 for (v=1; v<= Line.NbVertex(); v++) {
1333 Contap_Point& Vertex = Line.Vertex(v);
1334 if(Vertex.ParameterOnLine() == paramp) {
1335 Vertex.SetInternal();
1336 newpoint = Standard_False;
1337 }
1338 }
1339 }
1340
1341 if (newpoint && paramp >1. && paramp < Nbpnts) {
1342 // on doit creer un nouveau vertex.
1343 Contap_Point internalp(SFunc.Point(),X(1),X(2));
1344 internalp.SetParameter(paramp);
1345 internalp.SetInternal();
1346 Line.Add(internalp);
1347 }
1348 }
1349 Line.Point(indexsup).ParametersOnS2(XSup(1),XSup(2));
1350 }
1351 vecref = vectest;
1352 indexinf = indexsup;
1353 indexsup++;
1354 XInf = XSup;
1355 }
1356 toutvu = (indexsup > Nbpnts);
1357 }
1358}
1359
1360
1361void Contap_Contour::Perform
1362(const Handle(Adaptor3d_TopolTool)& Domain) {
1363
1364 done = Standard_False;
1365 slin.Clear();
1366
1367 Standard_Integer i,j,k,Nbvt1,Nbvt2,ivt1,ivt2;
1368 Standard_Integer NbPointRst,NbPointIns;
1369 Standard_Integer Nblines, Nbpts, indfirst, indlast;
1370 Standard_Real U,V;
1371 gp_Pnt2d pt2d;
1372 gp_Vec2d d2d;
1373 gp_Pnt ptonsurf;
1374 gp_Vec d1u,d1v,normale,tgtrst,tgline;
1375 Standard_Real currentparam;
1376 IntSurf_Transition TLine,TArc;
1377
1378 Contap_Line theline;
1379 Contap_Point ptdeb,ptfin;
1380 Contap_ThePathPointOfTheSearch PStartf,PStartl;
1381
1382 // Standard_Real TolArc = 1.e-5;
1383 Standard_Real TolArc = Precision::Confusion();
1384
1385 const Handle(Adaptor3d_HSurface)& Surf = mySFunc.Surface();
1386
1387 Standard_Real EpsU = Adaptor3d_HSurfaceTool::UResolution(Surf,Precision::Confusion());
1388 Standard_Real EpsV = Adaptor3d_HSurfaceTool::VResolution(Surf,Precision::Confusion());
1389 Standard_Real Preci = Min(EpsU,EpsV);
1390 // Standard_Real Fleche = 5.e-1;
1391 // Standard_Real Pas = 5.e-2;
1392 Standard_Real Fleche = 0.01;
1393 Standard_Real Pas = 0.005;
1394 // lbr: Il y avait Pas 0.2 -> Manque des Inters sur restr ; devrait faire un mini de 5 pts par lignes
1395 //-- le 23 janvier 98 0.05 -> 0.01
1396
1397
1398 //-- ******************************************************************************** Janvier 98
1399 Bnd_Box B1; Standard_Boolean Box1OK = Standard_True;
1400
1401 Standard_Real Uinf = Surf->FirstUParameter();
1402 Standard_Real Vinf = Surf->FirstVParameter();
1403 Standard_Real Usup = Surf->LastUParameter();
1404 Standard_Real Vsup = Surf->LastVParameter();
1405
1406 Standard_Boolean Uinfinfinite = Precision::IsNegativeInfinite(Uinf);
1407 Standard_Boolean Usupinfinite = Precision::IsPositiveInfinite(Usup);
1408 Standard_Boolean Vinfinfinite = Precision::IsNegativeInfinite(Vinf);
1409 Standard_Boolean Vsupinfinite = Precision::IsPositiveInfinite(Vsup);
1410
1411 if( Uinfinfinite || Usupinfinite || Vinfinfinite || Vsupinfinite) {
1412 Box1OK = Standard_False;
1413 }
1414 else {
1415 BndLib_AddSurface::Add(Surf->Surface(),1e-8,B1);
1416 }
1417 Standard_Real x0,y0,z0,x1,y1,z1,dx,dy,dz;
1418 if(Box1OK) {
1419 B1.Get(x0,y0,z0,x1,y1,z1);
1420 dx=x1-x0;
1421 dy=y1-y0;
1422 dz=z1-z0;
1423 }
1424 else {
1425 dx=dy=dz=1.0;
1426 }
1427 if(dx<dy) dx=dy;
1428 if(dx<dz) dx=dz;
1429 if(dx>10000.0) dx=10000.0;
1430 Fleche*=dx;
1431 TolArc*=dx;
1432 //-- ********************************************************************************
1433
1434
1435 //gp_Pnt valpt;
1436
1437 //jag 940616 SFunc.Set(1.e-8); // tolerance sur la fonction
1438 mySFunc.Set(Precision::Confusion()); // tolerance sur la fonction
1439
1440 Standard_Boolean RecheckOnRegularity = Standard_True;
1441 solrst.Perform(myAFunc,Domain,TolArc,TolArc,RecheckOnRegularity);
1442
1443 if (!solrst.IsDone()) {
1444 return;
1445 }
1446
1447 NbPointRst = solrst.NbPoints();
1448 IntSurf_SequenceOfPathPoint seqpdep;
1449 TColStd_Array1OfInteger Destination(1,NbPointRst+1);
1450 Destination.Init(0);
1451 if (NbPointRst != 0) {
1452 ComputeTangency(solrst,Domain,mySFunc,seqpdep,Destination);
1453 }
1454
1455 //jag 940616 solins.Perform(SFunc,Surf,Domain,1.e-6); // 1.e-6 : tolerance dans l espace.
1456 solins.Perform(mySFunc,Surf,Domain,Precision::Confusion());
1457
1458 NbPointIns = solins.NbPoints();
1459 IntSurf_SequenceOfInteriorPoint seqpins;
1460
1461 if (NbPointIns != 0) {
1462 Standard_Boolean bKeepAllPoints = Standard_False;
1463 //IFV begin
1464 if(solrst.NbSegments() <= 0) {
1465 if(mySFunc.FunctionType() == Contap_ContourStd) {
51740958 1466 const Handle(Adaptor3d_HSurface)& SurfToCheck = mySFunc.Surface();
1467 if(Adaptor3d_HSurfaceTool::GetType(SurfToCheck) == GeomAbs_Torus) {
1468 gp_Torus aTor = Adaptor3d_HSurfaceTool::Torus(SurfToCheck);
e2065c2f 1469 gp_Dir aTorDir = aTor.Axis().Direction();
1470 gp_Dir aProjDir = mySFunc.Direction();
1471
1472 if(aTorDir.Dot(aProjDir) < Precision::Confusion()) {
1473 bKeepAllPoints = Standard_True;
1474 }
1475 }
1476 }
1477 }
1478
1479 if(bKeepAllPoints) {
1480 Standard_Integer Nbp = solins.NbPoints(), indp;
1481 for (indp=1; indp <= Nbp; indp++) {
1482 const IntSurf_InteriorPoint& pti = solins.Value(indp);
1483 seqpins.Append(pti);
1484 }
1485 }
1486 //IFV - end
1487 else {
1488 KeepInsidePoints(solins,solrst,mySFunc,seqpins);
1489 }
1490 }
1491
1492 if (seqpdep.Length() != 0 || seqpins.Length() != 0) {
1493
8d795b51 1494 Standard_Boolean theToFillHoles = Standard_True;
1495 Contap_TheIWalking iwalk(Preci,Fleche,Pas,theToFillHoles);
e2065c2f 1496 iwalk.Perform(seqpdep,seqpins,mySFunc ,Surf);
1497 if(!iwalk.IsDone()) {
1498 return;
1499 }
1500
1501 Nblines = iwalk.NbLines();
1502 for (j=1; j<=Nblines; j++) {
1503 IntSurf_TypeTrans TypeTransOnS = IntSurf_Undecided;
1504 const Handle(Contap_TheIWLineOfTheIWalking)& iwline = iwalk.Value(j);
1505 Nbpts = iwline->NbPoints();
1506 theline.SetLineOn2S(iwline->Line());
1507
1508 // jag 941018 On calcule une seule fois la transition
1509
1510 tgline = iwline->TangentVector(k);
1511 iwline->Line()->Value(k).ParametersOnS2(U,V);
1512 TypeTransOnS = ComputeTransitionOnLine(mySFunc,U,V,tgline);
1513 theline.SetTransitionOnS(TypeTransOnS);
1514
1515 //---------------------------------------------------------------------
1516 //-- On ajoute a la liste des vertex les 1er et dernier points de la -
1517 //-- ligne de cheminement si ceux-ci ne sont pas presents -
1518 //---------------------------------------------------------------------
1519
1520 if (iwline->HasFirstPoint()) {
1521 indfirst = iwline->FirstPointIndex();
1522 const IntSurf_PathPoint& PPoint = seqpdep(indfirst);
1523 Standard_Integer themult = PPoint.Multiplicity();
1524 for (i=NbPointRst; i>=1; i--) {
1525 if (Destination(i) == indfirst) {
1526 PPoint.Parameters(themult,U,V);
1527 ptdeb.SetValue(PPoint.Value(),U,V);
1528 ptdeb.SetParameter(1.0);
1529
1530 const Contap_ThePathPointOfTheSearch& PStart = solrst.Point(i);
1531 const Handle(Adaptor2d_HCurve2d)& currentarc = PStart.Arc();
1532 currentparam = PStart.Parameter();
1533 if (!iwline->IsTangentAtBegining()) {
1534
1535 Contap_HCurve2dTool::D1(currentarc,currentparam,pt2d,d2d);
1536 Contap_SurfProps::DerivAndNorm(Surf,pt2d.X(),pt2d.Y(),
1537 ptonsurf,d1u,d1v,normale);
1538 tgtrst = d2d.X()*d1u;
1539 tgtrst.Add(d2d.Y()*d1v);
1540
1541 IntSurf::MakeTransition(PPoint.Direction3d(),tgtrst,normale,
1542 TLine,TArc);
1543
1544 }
1545 else {// a voir. En effet, on a cheminer. Si on est sur un point
1546 // debut, on sait qu'on rentre dans la matiere
1547 TLine.SetValue();
1548 TArc.SetValue();
1549 }
1550
1551 ptdeb.SetArc(currentarc,currentparam,TLine,TArc);
1552
1553 if (!solrst.Point(i).IsNew()) {
1554 ptdeb.SetVertex(PStart.Vertex());
1555 }
1556 theline.Add(ptdeb);
1557 themult--;
1558 }
1559 }
1560 }
1561 else {
1562 iwline->Value(1).ParametersOnS2(U,V);
1563 ptdeb.SetValue(theline.Point(1).Value(),U,V);
1564 ptdeb.SetParameter(1.0);
1565 theline.Add(ptdeb);
1566 }
1567
1568 if (iwline->HasLastPoint()) {
1569 indlast = iwline->LastPointIndex();
1570 const IntSurf_PathPoint& PPoint = seqpdep(indlast);
1571 Standard_Integer themult = PPoint.Multiplicity();
1572 for (i=NbPointRst; i>=1; i--) {
1573 if (Destination(i) == indlast) {
1574 PPoint.Parameters(themult,U,V);
1575 ptfin.SetValue(PPoint.Value(),U,V);
1576 ptfin.SetParameter((Standard_Real)(Nbpts));
1577 const Contap_ThePathPointOfTheSearch& PStart = solrst.Point(i);
1578 const Handle(Adaptor2d_HCurve2d)& currentarc = PStart.Arc();
1579 currentparam = PStart.Parameter();
1580
1581 if (!iwline->IsTangentAtEnd()) {
1582
1583 Contap_HCurve2dTool::D1(currentarc,currentparam,pt2d,d2d);
1584
1585 Contap_SurfProps::DerivAndNorm(Surf,pt2d.X(),pt2d.Y(),
1586 ptonsurf,d1u,d1v,normale);
1587 tgtrst = d2d.X()*d1u;
1588 tgtrst.Add(d2d.Y()*d1v);
1589 IntSurf::MakeTransition(PPoint.Direction3d().Reversed(),
1590 tgtrst,normale,TLine,TArc);
1591 }
1592 else {
1593 TLine.SetValue();
1594 TArc.SetValue();
1595 }
1596
1597 ptfin.SetArc(currentarc,currentparam,TLine,TArc);
1598
1599 if (!solrst.Point(i).IsNew()) {
1600 ptfin.SetVertex(PStart.Vertex());
1601 }
1602 theline.Add(ptfin);
1603 themult--;
1604 }
1605 }
1606 }
1607 else {
1608 iwline->Value(Nbpts).ParametersOnS2(U,V);
1609 ptfin.SetValue(theline.Point(Nbpts).Value(),U,V);
1610 ptfin.SetParameter((Standard_Real)(Nbpts));
1611 theline.Add(ptfin);
1612 }
1613
1614 ComputeInternalPoints(theline,mySFunc,EpsU,EpsV);
1615 LineConstructor(slin,Domain,theline,Surf); //-- lbr
1616 //-- slin.Append(theline);
1617 theline.ResetSeqOfVertex();
1618 }
1619
1620
1621 Nblines = slin.Length();
1622 for (j=1; j<=Nblines-1; j++) {
1623 const Contap_Line& theli = slin(j);
1624 Nbvt1 = theli.NbVertex();
1625 for (ivt1=1; ivt1<=Nbvt1; ivt1++) {
1626 if (!theli.Vertex(ivt1).IsOnArc()) {
1627 const gp_Pnt& pttg1 = theli.Vertex(ivt1).Value();
1628
1629 for (k=j+1; k<=Nblines;k++) {
1630 const Contap_Line& theli2 = slin(k);
1631 Nbvt2 = theli2.NbVertex();
1632 for (ivt2=1; ivt2<=Nbvt2; ivt2++) {
1633 if (!theli2.Vertex(ivt2).IsOnArc()) {
1634 const gp_Pnt& pttg2 = theli2.Vertex(ivt2).Value();
1635
1636 if (pttg1.Distance(pttg2) <= TolArc) {
1637 theli.Vertex(ivt1).SetMultiple();
1638 theli2.Vertex(ivt2).SetMultiple();
1639 }
1640 }
1641 }
1642 }
1643 }
1644 }
1645 }
1646 }
1647
1648 // jag 940620 On ajoute le traitement des restrictions solutions.
1649
1650 if (solrst.NbSegments() !=0) {
1651 ProcessSegments(solrst,slin,TolArc,mySFunc,Domain);
1652 }
1653
1654
1655 // Ajout crad pour depanner CMA en attendant mieux
1656 if (solrst.NbSegments() !=0) {
1657
1658 Nblines = slin.Length();
1659 for (j=1; j<=Nblines; j++) {
1660 const Contap_Line& theli = slin(j);
1661 if (theli.TypeContour() == Contap_Walking) {
1662 Nbvt1 = theli.NbVertex();
1663 for (ivt1=1; ivt1<=Nbvt1; ivt1++) {
1664 Contap_Point& ptvt = theli.Vertex(ivt1);
1665 if (!ptvt.IsOnArc() && !ptvt.IsMultiple()) {
1666 Standard_Real Up,Vp;
1667 ptvt.Parameters(Up,Vp);
1668 gp_Pnt2d toproj(Up,Vp);
1669 Standard_Boolean projok;
1670 for (k=1; k<=Nblines;k++) {
1671 if (slin(k).TypeContour() == Contap_Restriction) {
1672 const Handle(Adaptor2d_HCurve2d)& thearc = slin(k).Arc();
1673 Standard_Real paramproj;
1674 gp_Pnt2d Ptproj;
1675 projok = Contap_HContTool::Project(thearc,toproj,paramproj,Ptproj);
1676
1677 if (projok) {
1678 Standard_Real dist = Ptproj.Distance(gp_Pnt2d(Up,Vp));
1679 if (dist <= Preci) {
1680 // Calcul de la transition
1681
1682 Contap_HCurve2dTool::D1(thearc,paramproj,Ptproj,d2d);
1683 // Adaptor3d_HSurfaceTool::D1(Surf,Ptproj.X(),Ptproj.Y(),
1684 // ptonsurf,d1u,d1v);
1685 // normale = d1u.Crossed(d1v);
1686
1687 Contap_SurfProps::DerivAndNorm
1688 (Surf,Ptproj.X(),Ptproj.Y(),ptonsurf,d1u,d1v,normale);
1689
1690 tgtrst = d2d.X()*d1u;
1691 tgtrst.Add(d2d.Y()*d1v);
1692 Standard_Integer Paraml =
1693 (Standard_Integer) ptvt.ParameterOnLine();
1694
1695 if (Paraml == theli.NbPnts()) {
1696 tgline = gp_Vec(theli.Point(Paraml-1).Value(),
1697 ptvt.Value());
1698 }
1699 else {
1700 tgline = gp_Vec(ptvt.Value(),
1701 theli.Point(Paraml+1).Value());
1702 }
1703 IntSurf::MakeTransition(tgline,tgtrst,normale,
1704 TLine,TArc);
1705 ptvt.SetArc(thearc,paramproj,TLine,TArc);
1706 ptvt.SetMultiple();
1707 ptdeb.SetValue(ptonsurf,Ptproj.X(),Ptproj.Y());
1708 ptdeb.SetParameter(paramproj);
1709 ptdeb.SetMultiple();
1710 slin(k).Add(ptdeb);
1711 break;
1712 }
1713 else {
1714 projok = Standard_False;
1715 }
1716 }
1717 }
1718 else {
1719 projok = Standard_False;
1720 }
1721 if (projok) {
1722 break;
1723 }
1724 }
1725 }
1726 }
1727 }
1728 }
1729 }
1730 done = Standard_True;
1731}
1732
1733static Standard_Boolean FindLine(Contap_Line& Line,
1734 const Handle(Adaptor3d_HSurface)& Surf,
1735 const gp_Pnt2d& Pt2d,
1736 gp_Pnt& Ptref,
1737 Standard_Real& Paramin,
1738 gp_Vec& Tgmin,
1739 gp_Vec& Norm)
1740{
1741 // Standard_Integer i;
1742 gp_Pnt pt,ptmin;
1743 gp_Vec tg;
1744 Standard_Real para,dist;
1745 Standard_Real dismin = RealLast();
1746
1747 Contap_SurfProps::Normale(Surf,Pt2d.X(),Pt2d.Y(),Ptref,Norm);
1748
1749 if (Line.TypeContour() == Contap_Lin) {
1750 gp_Lin lin(Line.Line());
1751 para = ElCLib::Parameter(lin,Ptref);
1752 ElCLib::D1(para,lin,pt,tg);
1753 dist = pt.Distance(Ptref) + Abs(Norm.Dot(lin.Direction()));
1754 }
1755 else { // Contap__Circle
1756 gp_Circ cir(Line.Circle());
1757 para = ElCLib::Parameter(cir,Ptref);
1758 ElCLib::D1(para,cir,pt,tg);
1759 dist = pt.Distance(Ptref)+Abs(Norm.Dot(tg/cir.Radius()));
1760 }
1761 if (dist < dismin) {
1762 dismin = dist;
1763 Paramin = para;
1764 ptmin = pt;
1765 Tgmin = tg;
1766 }
1767 if (ptmin.SquareDistance(Ptref) <= Tolpetit) {
1768 return Standard_True;
1769 }
1770 else {
1771 return Standard_False;
1772 }
1773}
1774
1775
1776static void PutPointsOnLine (const Contap_TheSearch& solrst,
1777 const Handle(Adaptor3d_HSurface)& Surf,
1778 Contap_TheSequenceOfLine& slin)
1779
1780{
1781 Standard_Integer i,l;//,index;
1782 Standard_Integer NbPoints = solrst.NbPoints();
1783
1784 Standard_Real theparam;
1785
1786 IntSurf_Transition TLine,TArc;
1787 Standard_Boolean goon;
1788
1789 gp_Pnt2d pt2d;
1790 gp_Vec2d d2d;
1791
1792 gp_Pnt ptonsurf;
1793 gp_Vec vectg,normale,tgtrst;
1794 Standard_Real paramlin = 0.0;
1795
1796
1797 Standard_Integer nbLin = slin.Length();
1798 for(l=1;l<=nbLin;l++) {
1799 Contap_Line& Line=slin.ChangeValue(l);
1800 for (i=1; i<= NbPoints; i++) {
1801
1802 const Contap_ThePathPointOfTheSearch& PStart = solrst.Point(i);
1803 const Handle(Adaptor2d_HCurve2d)& thearc = PStart.Arc();
1804 theparam = PStart.Parameter();
1805
1806 Contap_HCurve2dTool::D1(thearc,theparam,pt2d,d2d);
1807 goon = FindLine(Line,Surf,pt2d,ptonsurf,paramlin,vectg,normale);
1808
1809 Contap_Point PPoint;
1810
1811 if (goon) {
1812 gp_Vec d1u,d1v;
1813 gp_Pnt bidpt;
1814 Adaptor3d_HSurfaceTool::D1(Surf,pt2d.X(),pt2d.Y(),bidpt,d1u,d1v);
1815 PPoint.SetValue(ptonsurf,pt2d.X(),pt2d.Y());
1816 if (normale.Magnitude() < RealEpsilon()) {
1817 TLine.SetValue();
1818 TArc.SetValue();
1819 }
1820 else {
1821 // Petit test qui devrait permettre de bien traiter les pointes
1822 // des cones, et les sommets d`une sphere. Il faudrait peut-etre
1823 // rajouter une methode dans SurfProps
1824
1825 if (Abs(d2d.Y()) <= Precision::Confusion()) {
1826 tgtrst = d1v.Crossed(normale);
1827 if(d2d.X() < 0.0)
1828 tgtrst.Reverse();
1829 }
1830 else {
1831 tgtrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1832 }
1833 IntSurf::MakeTransition(vectg,tgtrst,normale,TLine,TArc);
1834 }
1835
1836 PPoint.SetArc(thearc,theparam, TLine, TArc);
1837 PPoint.SetParameter(paramlin);
1838 if (!PStart.IsNew()) {
1839 PPoint.SetVertex(PStart.Vertex());
1840 }
1841 Line.Add(PPoint);
1842 }
1843 }
1844 }
1845}
1846
1847
1848//----------------------------------------------------------------------------------
1849//-- Orientation des contours Apparents quand ceux-ci sont des lignes ou des cercles
1850//-- On prend un point de la ligne ou du cercle ---> P
1851//-- On projete ce point sur la surface P ---> u,v
1852//-- et on evalue la transition au point u,v
1853//----------------------------------------------------------------------------------
1854
1855IntSurf_TypeTrans ComputeTransitionOngpLine
1856(Contap_SurfFunction& SFunc,
1857 const gp_Lin& L)
1858{
1859 const Handle(Adaptor3d_HSurface)& Surf=SFunc.Surface();
1860 GeomAbs_SurfaceType typS = Adaptor3d_HSurfaceTool::GetType(Surf);
1861 gp_Pnt P;
1862 gp_Vec T;
1863 ElCLib::D1(0.0,L,P,T);
1864 Standard_Real u = 0.,v = 0.;
1865 switch (typS) {
1866 case GeomAbs_Cylinder: {
1867 ElSLib::Parameters(Adaptor3d_HSurfaceTool::Cylinder(Surf),P,u,v);
1868 break;
1869 }
1870 case GeomAbs_Cone: {
1871 ElSLib::Parameters(Adaptor3d_HSurfaceTool::Cone(Surf),P,u,v);
1872 break;
1873 }
1874 case GeomAbs_Sphere: {
1875 ElSLib::Parameters(Adaptor3d_HSurfaceTool::Sphere(Surf),P,u,v);
1876 break;
1877 }
1878 default:
1879 break;
1880 }
1881 return(ComputeTransitionOnLine(SFunc,u,v,T));
1882}
1883
1884
1885IntSurf_TypeTrans ComputeTransitionOngpCircle
1886(Contap_SurfFunction& SFunc,
1887 const gp_Circ& C)
1888{
1889 const Handle(Adaptor3d_HSurface)& Surf=SFunc.Surface();
1890 GeomAbs_SurfaceType typS = Adaptor3d_HSurfaceTool::GetType(Surf);
1891 gp_Pnt P;
1892 gp_Vec T;
1893 ElCLib::D1(0.0,C,P,T);
1894 Standard_Real u = 0.,v = 0.;
1895 switch (typS) {
1896 case GeomAbs_Cylinder: {
1897 ElSLib::Parameters(Adaptor3d_HSurfaceTool::Cylinder(Surf),P,u,v);
1898 break;
1899 }
1900 case GeomAbs_Cone: {
1901 ElSLib::Parameters(Adaptor3d_HSurfaceTool::Cone(Surf),P,u,v);
1902 break;
1903 }
1904 case GeomAbs_Sphere: {
1905 ElSLib::Parameters(Adaptor3d_HSurfaceTool::Sphere(Surf),P,u,v);
1906 break;
1907 }
1908 default:
1909 break;
1910 }
1911 return(ComputeTransitionOnLine(SFunc,u,v,T));
1912}
1913
1914
1915void Contap_Contour::PerformAna(const Handle(Adaptor3d_TopolTool)& Domain)
1916{
1917
1918 done = Standard_False;
1919 slin.Clear();
1920
1921 Standard_Real TolArc = 1.e-5;
1922
1923 Standard_Integer nbCont, nbPointRst, i;
1924 //gp_Circ cirsol;
1925 //gp_Lin linsol;
1926 Contap_ContAna contana;
1927 Contap_Line theline;
1928 const Handle(Adaptor3d_HSurface)& Surf = mySFunc.Surface();
1929 Contap_TFunction TypeFunc(mySFunc.FunctionType());
1930 Standard_Boolean PerformSolRst = Standard_True;
1931
1932 GeomAbs_SurfaceType typS = Adaptor3d_HSurfaceTool::GetType(Surf);
1933
1934 switch (typS) {
1935 case GeomAbs_Plane:
1936 {
1937 gp_Pln pl(Adaptor3d_HSurfaceTool::Plane(Surf));
1938 switch (TypeFunc) {
1939 case Contap_ContourStd:
1940 {
1941 gp_Dir Dirpln(pl.Axis().Direction());
1942 if (Abs(mySFunc.Direction().Dot(Dirpln)) > Precision::Angular()) {
1943 // Aucun point du plan n`est solution, en particulier aucun point
1944 // sur restriction.
1945 PerformSolRst = Standard_False;
1946 }
1947 }
1948 break;
1949 case Contap_ContourPrs:
1950 {
1951 gp_Pnt Eye(mySFunc.Eye());
1952 if (pl.Distance(Eye) > Precision::Confusion()) {
1953 // Aucun point du plan n`est solution, en particulier aucun point
1954 // sur restriction.
1955 PerformSolRst = Standard_False;
1956 }
1957 }
1958 break;
1959 case Contap_DraftStd:
1960 {
1961 gp_Dir Dirpln(pl.Axis().Direction());
1962 Standard_Real Sina = Sin(mySFunc.Angle());
1963 if (Abs(mySFunc.Direction().Dot(Dirpln)+ Sina) > //voir SurfFunction
1964 Precision::Angular()) {
1965
1966 PerformSolRst = Standard_False;
1967 }
1968 }
1969 break;
1970 case Contap_DraftPrs:
1971 default:
1972 {
1973 }
1974 }
1975 }
1976 break;
1977
1978 case GeomAbs_Sphere:
1979 {
1980 switch (TypeFunc) {
1981 case Contap_ContourStd:
1982 {
1983 contana.Perform(Adaptor3d_HSurfaceTool::Sphere(Surf),mySFunc.Direction());
1984 }
1985 break;
1986 case Contap_ContourPrs:
1987 {
1988 contana.Perform(Adaptor3d_HSurfaceTool::Sphere(Surf),mySFunc.Eye());
1989 }
1990 break;
1991 case Contap_DraftStd:
1992 {
1993 contana.Perform(Adaptor3d_HSurfaceTool::Sphere(Surf),
1994 mySFunc.Direction(),mySFunc.Angle());
1995 }
1996 break;
1997 case Contap_DraftPrs:
1998 default:
1999 {
2000 }
2001 }
2002 }
2003 break;
2004
2005 case GeomAbs_Cylinder:
2006 {
2007 switch (TypeFunc) {
2008 case Contap_ContourStd:
2009 {
2010 contana.Perform(Adaptor3d_HSurfaceTool::Cylinder(Surf),mySFunc.Direction());
2011 }
2012 break;
2013 case Contap_ContourPrs:
2014 {
2015 contana.Perform(Adaptor3d_HSurfaceTool::Cylinder(Surf),mySFunc.Eye());
2016 }
2017 break;
2018 case Contap_DraftStd:
2019 {
2020 contana.Perform(Adaptor3d_HSurfaceTool::Cylinder(Surf),
2021 mySFunc.Direction(),mySFunc.Angle());
2022 }
2023 break;
2024 case Contap_DraftPrs:
2025 default:
2026 {
2027 }
2028 }
2029 }
2030 break;
2031
2032 case GeomAbs_Cone:
2033 {
2034 switch (TypeFunc) {
2035 case Contap_ContourStd:
2036 {
2037 contana.Perform(Adaptor3d_HSurfaceTool::Cone(Surf),mySFunc.Direction());
2038 }
2039 break;
2040 case Contap_ContourPrs:
2041 {
2042 contana.Perform(Adaptor3d_HSurfaceTool::Cone(Surf),mySFunc.Eye());
2043 }
2044 break;
2045 case Contap_DraftStd:
2046 {
2047 contana.Perform(Adaptor3d_HSurfaceTool::Cone(Surf),
2048 mySFunc.Direction(),mySFunc.Angle());
2049 }
2050 break;
2051 case Contap_DraftPrs:
2052 default:
2053 {
2054 }
2055 }
2056 default:
2057 break;
2058 }
2059 break;
2060 }
2061
2062 if (typS != GeomAbs_Plane) {
2063
2064 if (!contana.IsDone()) {
2065 return;
2066 }
2067
2068 nbCont = contana.NbContours();
2069
2070 if (contana.NbContours() == 0) {
2071 done = Standard_True;
2072 return;
2073 }
2074
2075 GeomAbs_CurveType typL = contana.TypeContour();
2076 if (typL == GeomAbs_Circle) {
2077 theline.SetValue(contana.Circle());
2078 IntSurf_TypeTrans TransCircle;
2079 TransCircle = ComputeTransitionOngpCircle(mySFunc,contana.Circle());
2080 theline.SetTransitionOnS(TransCircle);
2081 slin.Append(theline);
2082 }
2083 else if (typL == GeomAbs_Line) {
2084 for (i=1; i<=nbCont; i++) {
2085 theline.SetValue(contana.Line(i));
2086 IntSurf_TypeTrans TransLine;
2087 TransLine = ComputeTransitionOngpLine(mySFunc,contana.Line(i));
2088 theline.SetTransitionOnS(TransLine);
2089 slin.Append(theline);
2090 theline.Clear();
2091 }
2092
2093 /*
2094 if (typS == GeomAbs_Cone) {
2095 Standard_Real u,v;
2096 gp_Cone thecone(Adaptor3d_HSurfaceTool::Cone(Surf));
2097 ElSLib::Parameters(thecone,thecone.Apex(),u,v);
2098 Contap_Point vtxapex(thecone.Apex(),u,v);
2099 vtxapex.SetInternal();
2100 vtxapex.SetMultiple();
2101 for (i=1; i<=nbCont i++) {
2102 slin.ChangeValue(i).Add(vtxapex);
2103 }
2104 }
2105 */
2106 }
2107 }
2108
2109 if(PerformSolRst) {
2110
2111 solrst.Perform(myAFunc,Domain,TolArc,TolArc);
2112 if (!solrst.IsDone()) {
2113 return;
2114 }
2115 nbPointRst = solrst.NbPoints();
2116
2117 if (nbPointRst != 0) {
2118 PutPointsOnLine(solrst,Surf,slin);
2119 }
2120
2121 if (solrst.NbSegments() !=0) {
2122 ProcessSegments(solrst,slin,TolArc,mySFunc,Domain);
2123 }
2124
2125
2126 //-- lbr
2127 //Standard_Boolean oneremov;
2128 Standard_Integer nblinto = slin.Length();
2129 TColStd_SequenceOfInteger SeqToDestroy;
2130
2131 //-- cout<<" Construct Contour_3 nblin = "<<nblinto<<endl;
2132 for(i=1; i<= nblinto ; i++) {
2133 //-- cout<<" nbvtx : "<<slin.Value(i).NbVertex()<<endl;
2134 //--if(slin.Value(i).NbVertex() > 1) {
2135 if(slin.Value(i).TypeContour() != Contap_Restriction) {
2136 LineConstructor(slin,Domain,slin.ChangeValue(i),Surf);
2137 SeqToDestroy.Append(i);
2138 }
2139 //-- }
2140 }
2141 for(i=SeqToDestroy.Length(); i>=1; i--) {
2142 slin.Remove(SeqToDestroy.Value(i));
2143 }
2144 }
2145
2146 done = Standard_True;
2147}
2148