0026936: Drawbacks of inlining in new type system in OCCT 7.0 -- automatic
[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();
471 if (Nba <= 0) return;
472 Standard_Integer Nbp,indp,inda;
473 Standard_Real U,V,paramproj;
474 gp_Pnt2d toproj,Ptproj;
475 Standard_Boolean projok,tokeep;
476 const Handle(Adaptor3d_HSurface)& Surf = Func.Surface();
477
478 Nbp = solins.NbPoints();
479 for (indp=1; indp <= Nbp; indp++) {
480 tokeep = Standard_True;
481 const IntSurf_InteriorPoint& pti = solins.Value(indp);
482 pti.Parameters(U,V);
483 toproj = gp_Pnt2d(U,V);
484 for (inda = 1; inda <= Nba; inda++) {
485 const Handle(Adaptor2d_HCurve2d)& thearc = solrst.Segment(inda).Curve();
486 projok = Contap_HContTool::Project(thearc,toproj,paramproj,Ptproj);
487 if (projok) {
488 gp_Pnt pprojete = Adaptor3d_HSurfaceTool::Value(Surf,Ptproj.X(),Ptproj.Y());
489 if (pti.Value().Distance(pprojete) <= Precision::Confusion()) {
490 tokeep = Standard_False;
491 break;
492 }
493 }
494 }
495 if (tokeep) {
496 seqpins.Append(pti);
497 }
498 }
499}
500
501
502static void ComputeTangency (const Contap_TheSearch& solrst,
503 const Handle(Adaptor3d_TopolTool)& Domain,
504 Contap_SurfFunction& Func,
505 IntSurf_SequenceOfPathPoint& seqpdep,
506 TColStd_Array1OfInteger& Destination)
507{
508
509 Standard_Integer i,k;
510 Standard_Integer NbPoints = solrst.NbPoints();
511 Standard_Integer seqlength = 0;
512
513 Standard_Real theparam,test;
514 Standard_Boolean fairpt;
515 TopAbs_Orientation arcorien,vtxorien;
516 Standard_Boolean ispassing;
517
518 math_Vector X(1, 2);
519 math_Vector F(1, 1);
520 math_Matrix D(1, 1, 1, 2);
521
522 gp_Vec normale, vectg, tg3drst,v1,v2;
523 gp_Dir2d dirtg;
524 gp_Vec2d tg2drst;
525 gp_Pnt2d pt2d;
526
527 IntSurf_PathPoint PPoint;
528 const Handle(Adaptor3d_HSurface)& Surf = Func.Surface();
529
530 for (i=1; i<= NbPoints; i++) {
531
532 if (Destination(i) == 0) {
533
534 const Contap_ThePathPointOfTheSearch& PStart = solrst.Point(i);
535 const Handle(Adaptor2d_HCurve2d)& thearc = PStart.Arc();
536 theparam = PStart.Parameter();
537 gp_Pnt2d Ptoproj=Contap_HCurve2dTool::Value(thearc,theparam);
538 //-- lbr le 15 mai 97
539 //-- On elimine les points qui sont egalement present sur une restriction solution
540 Standard_Boolean SurUneRestrictionSolution = Standard_False;
541 for(Standard_Integer restriction=1;
542 SurUneRestrictionSolution==Standard_False && restriction<=solrst.NbSegments();
543 restriction++) {
544 const Handle(Adaptor2d_HCurve2d)& thearcsol = solrst.Segment(restriction).Curve();
545 Standard_Real paramproj;
546 gp_Pnt2d pproj;
547 Standard_Boolean projok = Contap_HContTool::Project(thearcsol,Ptoproj,paramproj,pproj);
548 if(projok) {
549 //gp_Pnt pprojete = Adaptor3d_HSurfaceTool::Value(Surf,Ptoproj.X(),Ptoproj.Y());
550 //IFV - begin
551 gp_Pnt pprojete = Adaptor3d_HSurfaceTool::Value(Surf,pproj.X(),pproj.Y());
552 //IFV - end
553 if ((PStart.Value()).Distance(pprojete) <= Precision::Confusion()) {
554 SurUneRestrictionSolution = Standard_True;
555 }
556 }
557 }
558 if(SurUneRestrictionSolution == Standard_False) {
559 arcorien = Domain->Orientation(thearc);
560 ispassing = (arcorien == TopAbs_INTERNAL ||
561 arcorien == TopAbs_EXTERNAL);
562
563 Contap_HCurve2dTool::D1(thearc,theparam,pt2d,tg2drst);
564 X(1) = pt2d.X();
565 X(2) = pt2d.Y();
566 PPoint.SetValue(PStart.Value(),X(1),X(2));
567
568 Func.Values(X,F,D);
569 if (Func.IsTangent()) {
570 PPoint.SetTangency(Standard_True);
571 Destination(i) = seqlength+1;
572 if (!PStart.IsNew()) {
573 const Handle(Adaptor3d_HVertex)& vtx = PStart.Vertex();
574 for (k=i+1; k<=NbPoints; k++) {
575 if (Destination(k) ==0) {
576 const Contap_ThePathPointOfTheSearch& PStart2 = solrst.Point(k);
577 if (!PStart2.IsNew()) {
578 const Handle(Adaptor3d_HVertex)& vtx2 = PStart2.Vertex();
579 if (Domain->Identical(vtx,vtx2)) {
580 const Handle(Adaptor2d_HCurve2d)& thearc2 = PStart2.Arc();
581 theparam = PStart2.Parameter();
582 arcorien = Domain->Orientation(thearc2);
583 ispassing = ispassing && (arcorien == TopAbs_INTERNAL ||
584 arcorien == TopAbs_EXTERNAL);
585
586 pt2d = Contap_HCurve2dTool::Value(thearc2,theparam);
587 X(1) = pt2d.X();
588 X(2) = pt2d.Y();
589 PPoint.AddUV(X(1),X(2));
590 Destination(k) = seqlength+1;
591 }
592 }
593 }
594 }
595 }
596 PPoint.SetPassing(ispassing);
597 seqpdep.Append(PPoint);
598 seqlength++;
599 }
600 else { // on a un point de depart potentiel
601
602 vectg = Func.Direction3d();
603 dirtg = Func.Direction2d();
604
605 gp_Pnt ptbid;
606 // Adaptor3d_HSurfaceTool::D1(Surf,X(1),X(2),ptbid,v1,v2);
607 Contap_SurfProps::DerivAndNorm(Surf,X(1),X(2),ptbid,v1,v2,normale);
608 tg3drst = tg2drst.X()*v1 + tg2drst.Y()*v2;
609 // normale = v1.Crossed(v2);
610 if(normale.SquareMagnitude() < RealEpsilon()) {
611 //-- cout<<"\n*** Contap_ContourGen_2.gxx Normale Nulle en U:"<<X(1)<<" V:"<<X(2)<<endl;
612 }
613 else {
614 test = vectg.Dot(normale.Crossed(tg3drst));
615
616 if (PStart.IsNew()) {
617 Standard_Real tbis = vectg.Normalized().Dot(tg3drst.Normalized());
618 if (Abs(tbis) < 1.-tole) {
619
620 if ((test < 0. && arcorien == TopAbs_FORWARD) ||
621 (test > 0. && arcorien == TopAbs_REVERSED)) {
622 vectg.Reverse();
623 dirtg.Reverse();
624 }
625 PPoint.SetDirections(vectg,dirtg);
626 }
627 else { // on garde le point comme point d`arret (tangent)
628 PPoint.SetTangency(Standard_True);
629 }
630 PPoint.SetPassing(ispassing);
631 Destination(i) = seqlength+1;
632 seqpdep.Append(PPoint);
633 seqlength++;
634 }
635 else { // traiter la transition complexe
636 gp_Dir bidnorm(1.,1.,1.);
637
638 Standard_Boolean tobeverified = Standard_False;
639 TopAbs_Orientation LocTrans;
640 TopTrans_CurveTransition comptrans;
641 comptrans.Reset(vectg,bidnorm,0.);
642 if (arcorien != TopAbs_INTERNAL &&
643 arcorien != TopAbs_EXTERNAL) {
644 // pour essai
645 const Handle(Adaptor3d_HVertex)& vtx = PStart.Vertex();
646 vtxorien = Domain->Orientation(vtx);
647 test = test/(vectg.Magnitude());
648 test = test/((normale.Crossed(tg3drst)).Magnitude());
649
650 if (Abs(test) <= tole) {
651 tobeverified = Standard_True;
652 LocTrans = TopAbs_EXTERNAL; // et pourquoi pas INTERNAL
653 }
654 else {
655 if ((test > 0. && arcorien == TopAbs_FORWARD) ||
656 (test < 0. && arcorien == TopAbs_REVERSED)){
657 LocTrans = TopAbs_FORWARD;
658 }
659 else {
660 LocTrans = TopAbs_REVERSED;
661 }
662 if (arcorien == TopAbs_REVERSED) {tg3drst.Reverse();} // pas deja fait ???
663 }
664
665 comptrans.Compare(tole,tg3drst,bidnorm,0.,LocTrans,vtxorien);
666 }
667 Destination(i) = seqlength+1;
668 for (k= i+1; k<=NbPoints; k++) {
669 if (Destination(k) == 0) {
670 const Contap_ThePathPointOfTheSearch& PStart2 = solrst.Point(k);
671 if (!PStart2.IsNew()) {
672 const Handle(Adaptor3d_HVertex)& vtx2 = PStart2.Vertex();
673 if (Domain->Identical(PStart.Vertex(),vtx2)) {
674 const Handle(Adaptor2d_HCurve2d)& thearc2 = PStart2.Arc();
675 theparam = PStart2.Parameter();
676 arcorien = Domain->Orientation(thearc2);
677
678 Contap_HCurve2dTool::D1(thearc2,theparam,pt2d,tg2drst);
679 X(1) = pt2d.X();
680 X(2) = pt2d.Y();
681 PPoint.AddUV(X(1),X(2));
682
683 if (arcorien != TopAbs_INTERNAL &&
684 arcorien != TopAbs_EXTERNAL) {
685 ispassing = Standard_False;
686 tg3drst = tg2drst.X()*v1 + tg2drst.Y()*v2;
687 test = vectg.Dot(normale.Crossed(tg3drst));
688 test = test/(vectg.Magnitude());
689 test = test /((normale.Crossed(tg3drst)).Magnitude());
690
691 vtxorien = Domain->Orientation(vtx2);
692 if (Abs(test) <= tole) {
693 tobeverified = Standard_True;
694 LocTrans = TopAbs_EXTERNAL; // et pourquoi pas INTERNAL
695 }
696 else {
697 if ((test > 0. && arcorien == TopAbs_FORWARD) ||
698 (test < 0. && arcorien == TopAbs_REVERSED)){
699 LocTrans = TopAbs_FORWARD;
700 }
701 else {
702 LocTrans = TopAbs_REVERSED;
703 }
704 if (arcorien == TopAbs_REVERSED) {tg3drst.Reverse();} //deja fait????
705 }
706
707 comptrans.Compare(tole,tg3drst,bidnorm,0.,LocTrans,vtxorien);
708 }
709 Destination(k) = seqlength+1;
710 }
711 }
712 }
713 }
714 fairpt = Standard_True;
715 if (!ispassing) {
716 TopAbs_State Before = comptrans.StateBefore();
717 TopAbs_State After = comptrans.StateAfter();
718 if ((Before == TopAbs_UNKNOWN)||(After == TopAbs_UNKNOWN)) {
719 fairpt = Standard_False;
720 }
721 else if (Before == TopAbs_IN) {
722 if (After == TopAbs_IN) {
723 ispassing = Standard_True;
724 }
725 else {
726 vectg.Reverse();
727 dirtg.Reverse();
728 }
729 }
730 else {
731 if (After !=TopAbs_IN) {
732 fairpt = Standard_False;
733 }
734 }
735 }
736
737 // evite de partir le long d une restriction solution
738
739 if (fairpt && tobeverified) {
740 for (k=i; k <=NbPoints ; k++) {
741 if (Destination(k)==seqlength + 1) {
742 theparam = solrst.Point(k).Parameter();
743 const Handle(Adaptor2d_HCurve2d)& thearc2 = solrst.Point(k).Arc();
744 arcorien = Domain->Orientation(thearc2);
745
746 if (arcorien == TopAbs_FORWARD ||
747 arcorien == TopAbs_REVERSED) {
748 Contap_HCurve2dTool::D1(thearc2,theparam,pt2d,tg2drst);
749 tg3drst = tg2drst.X()*v1 + tg2drst.Y()*v2;
750 vtxorien = Domain->Orientation(solrst.Point(k).Vertex());
751 if ((arcorien == TopAbs_FORWARD &&
752 vtxorien == TopAbs_REVERSED) ||
753 (arcorien == TopAbs_REVERSED &&
754 vtxorien == TopAbs_FORWARD)) {
755 tg3drst.Reverse();
756 }
757 test = vectg.Normalized().Dot(tg3drst.Normalized());
758 if (test >= 1. - tole) {
759 fairpt = Standard_False;
760 break;
761 }
762 }
763 }
764 }
765 }
766
767 if (fairpt) {
768 PPoint.SetDirections(vectg,dirtg);
769 PPoint.SetPassing(ispassing);
770 seqpdep.Append(PPoint);
771 seqlength++;
772 }
773 else { // il faut remettre en "ordre" si on ne garde pas le point.
774 for (k=i; k <=NbPoints ; k++) {
775 if (Destination(k)==seqlength + 1) {
776 Destination(k) = -Destination(k);
777 }
778 }
779 }
780 }
781 }
782 }
783 }
784 }
785 }
786}
787
788
789IntSurf_TypeTrans ComputeTransitionOnLine(Contap_SurfFunction& SFunc,
790 const Standard_Real u,
791 const Standard_Real v,
792 const gp_Vec& tgline)
793{
794 gp_Vec d1u,d1v;
795 gp_Pnt pntbid;
796 //gp_Vec tglineuv;
797
798 Adaptor3d_HSurfaceTool::D1(SFunc.Surface(),u,v,pntbid,d1u,d1v);
799
800 //------------------------------------------------------
801 //-- Calcul de la tangente dans l espace uv ---
802 //------------------------------------------------------
803
804 Standard_Real det,d1uT,d1vT,normu2,normv2,d1ud1v,alpha,beta;
805 d1uT = d1u.Dot(tgline);
806 d1vT = d1v.Dot(tgline);
807 normu2 = d1u.Dot(d1u);
808 normv2 = d1v.Dot(d1v);
809 d1ud1v = d1u.Dot(d1v);
810 det = normu2 * normv2 - d1ud1v * d1ud1v;
811 if(det<RealEpsilon()) {
812 //-- On ne doit pas passer ici !!
813 //-- cout<<" Probleme !!!"<<endl ;
814 return IntSurf_Undecided;
815 }
816
817 alpha = (d1uT * normv2 - d1vT * d1ud1v)/det;
818 beta = (normu2 * d1vT - d1ud1v * d1uT)/det;
819 //-----------------------------------------------------
820 //-- Calcul du Gradient de la fonction Utilisee --
821 //-- pour le contour apparent --
822 //-----------------------------------------------------
823
824 Standard_Real v1,v2;
825 math_Vector X(1,2);
826 math_Matrix Df(1,1,1,2);
827 X(1) = u;
828 X(2) = v;
829 SFunc.Derivatives(X,Df);
830 v1 = Df(1,1);
831 v2 = Df(1,2);
832
833 //-----------------------------------------------------
834 //-- On calcule si la fonction --
835 //-- F(.) = Normale . Dir_Regard --
836 //-- Croit Losrque l on se deplace sur la Gauche --
837 //-- de la direction de deplacement sur la ligne. --
838 //-----------------------------------------------------
839
840 det = -v1*beta + v2*alpha;
841
842 if(det<RealEpsilon()) { // revoir le test jag 940620
843 return IntSurf_Undecided;
844 }
845 if(det>0.0) {
846 return(IntSurf_Out);
847 }
848 return(IntSurf_In);
849}
850
851
852void ProcessSegments (const Contap_TheSearch& solrst,
853 Contap_TheSequenceOfLine& slin,
854 const Standard_Real TolArc,
855 Contap_SurfFunction& SFunc,
856 const Handle(Adaptor3d_TopolTool)& Domain)
857
858{
859 Standard_Integer i,j,k;
860 Standard_Integer nbedg = solrst.NbSegments();
861 Standard_Integer Nblines,Nbpts;
862
863 Handle(Adaptor2d_HCurve2d) arcRef;
864 Contap_Point ptvtx;
865
866 Contap_ThePathPointOfTheSearch PStartf,PStartl;
867
868 Standard_Boolean dofirst,dolast,procf,procl;
869 Standard_Real paramf =0.,paraml =0.,U;
870 Contap_Line theline;
871
872 gp_Vec tgline;//,norm1,norm2;
873 gp_Pnt valpt;
874
875 gp_Vec d1u,d1v;
876 gp_Pnt2d p2d;
877 gp_Vec2d d2d;
878
879
880 for (i = 1; i <= nbedg; i++) {
881
882 const Contap_TheSegmentOfTheSearch& thesegsol = solrst.Segment(i);
883 theline.SetValue(thesegsol.Curve());
884
885 // Traitement des points debut/fin du segment solution.
886
887 dofirst = Standard_False;
888 dolast = Standard_False;
889 procf = Standard_False;
890 procl = Standard_False;
891
892 if (thesegsol.HasFirstPoint()) {
893 dofirst = Standard_True;
894 PStartf = thesegsol.FirstPoint();
895 paramf = PStartf.Parameter();
896 }
897 if (thesegsol.HasLastPoint()) {
898 dolast = Standard_True;
899 PStartl = thesegsol.LastPoint();
900 paraml = PStartl.Parameter();
901 }
902
903 // determination de la transition
904 if (dofirst && dolast) {
905 U = (paramf+paraml)/2.;
906 }
907 else if (dofirst) {
908 U = paramf + 1.0;
909 }
910 else if (dolast) {
911 U = paraml - 1.0;
912 }
913 else {
914 U = 0.0;
915 }
916
917 Contap_HCurve2dTool::D1(thesegsol.Curve(),U,p2d,d2d);
918 Adaptor3d_HSurfaceTool::D1(SFunc.Surface(),p2d.X(),p2d.Y(),valpt,d1u,d1v);
919 tgline.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
920 IntSurf_TypeTrans tral =
921 ComputeTransitionOnLine(SFunc,p2d.X(),p2d.Y(),tgline);
922
923 theline.SetTransitionOnS(tral);
924
925
926 if (dofirst || dolast) {
927 Nblines = slin.Length();
928 for (j=1; j<=Nblines; j++) {
929 Nbpts = slin(j).NbVertex();
930 for (k=1; k<=Nbpts;k++) {
931 ptvtx = slin(j).Vertex(k);
932 if (dofirst) {
933 if (ptvtx.Value().Distance(PStartf.Value()) <=TolArc) {
934 slin(j).Vertex(k).SetMultiple();
935 ptvtx.SetMultiple();
936 ptvtx.SetParameter(paramf);
937 theline.Add(ptvtx);
938 procf=Standard_True;
939 }
940 }
941 if (dolast) {
942 if (ptvtx.Value().Distance(PStartl.Value()) <=TolArc) {
943 slin(j).Vertex(k).SetMultiple();
944 ptvtx.SetMultiple();
945 ptvtx.SetParameter(paraml);
946 theline.Add(ptvtx);
947 procl=Standard_True;
948 }
949 }
950 }
951 // Si on a traite le pt debut et/ou fin, on ne doit pas recommencer si
952 // il (ils) correspond(ent) a un point multiple.
953
954 if (procf) {
955 dofirst = Standard_False;
956 }
957 if (procl) {
958 dolast = Standard_False;
959 }
960 }
961 }
962
963 // Si on n a pas trouve le point debut et./ou fin sur une des lignes
964 // d intersection, il faut quand-meme le placer sur la restriction solution
965
966 if (dofirst) {
967
968 p2d = Contap_HCurve2dTool::Value(thesegsol.Curve(),paramf);
969 ptvtx.SetValue(PStartf.Value(),p2d.X(),p2d.Y());
970 ptvtx.SetParameter(paramf);
971 if (! PStartf.IsNew()) {
972 ptvtx.SetVertex(PStartf.Vertex());
973 }
974 theline.Add(ptvtx);
975 }
976 if (dolast) {
977 p2d = Contap_HCurve2dTool::Value(thesegsol.Curve(),paraml);
978 ptvtx.SetValue(PStartl.Value(),p2d.X(),p2d.Y());
979 ptvtx.SetParameter(paraml);
980 if (! PStartl.IsNew()) {
981 ptvtx.SetVertex(PStartl.Vertex());
982 }
983 theline.Add(ptvtx);
984 }
985
986 // il faut chercher le points internal sur les restrictions solutions.
987 if (thesegsol.HasFirstPoint() && thesegsol.HasLastPoint()) {
988 ComputeInternalPointsOnRstr(theline,paramf,paraml,SFunc);
989 }
990 LineConstructor(slin,Domain,theline,SFunc.Surface()); //-- lbr
991 //-- slin.Append(theline);
992 theline.Clear();
993 }
994}
995
996void ComputeInternalPointsOnRstr
997(Contap_Line& Line,
998 const Standard_Real Paramf,
999 const Standard_Real Paraml,
1000 Contap_SurfFunction& SFunc)
1001{
1002 // On recherche les points ou la tangente a la ligne de contour et
1003 // la direction sont alignees.
1004 // 1ere etape : recherche de changement de signe.
1005 // 2eme etape : localisation de la solution par dichotomie
1006
1007
1008 Standard_Integer indexinf,indexsup,i;
1009 gp_Vec tgt, vecref, vectest, vtestb, vecregard,d1u,d1v;
1010 gp_Pnt pcour;
1011 gp_Pnt2d p2d;
1012 gp_Vec2d d2d;
1013 Standard_Boolean found,ok = Standard_False,toutvu,solution;
1014 Standard_Real paramp = 0.,paraminf,paramsup,toler;
1015
1016 if (Line.TypeContour() != Contap_Restriction) {
1017 return;
1018 }
1019
857ffd5e 1020 const Handle(Adaptor2d_HCurve2d)& thearc = Line.Arc();
e2065c2f 1021
1022 const Handle(Adaptor3d_HSurface)& Surf = SFunc.Surface();
1023 Contap_TFunction TypeFunc(SFunc.FunctionType());
1024
1025 Standard_Integer Nbpnts = Contap_HContTool::NbSamplesOnArc(thearc);
1026 indexinf = 1;
1027 vecregard = SFunc.Direction();
1028 toler = Contap_HCurve2dTool::Resolution(thearc,Precision::Confusion());
1029 found = Standard_False;
1030
1031 do {
1032 paraminf = ((Nbpnts-indexinf)*Paramf + (indexinf-1)*Paraml)/(Nbpnts-1);
1033 Contap_HCurve2dTool::D1(thearc,paraminf,p2d,d2d);
1034 Adaptor3d_HSurfaceTool::D1(Surf,p2d.X(),p2d.Y(),pcour,d1u,d1v);
1035 tgt.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1036
1037 if (tgt.Magnitude() > gp::Resolution()) {
1038 if (TypeFunc == Contap_ContourPrs || TypeFunc==Contap_DraftPrs) {
1039 vecregard.SetXYZ(pcour.XYZ()-SFunc.Eye().XYZ());
1040 }
1041 vecref = vecregard.Crossed(tgt);
1042
1043 if (vecref.Magnitude() <= gp::Resolution()) {
1044 indexinf++;
1045 }
1046 else {
1047 found = Standard_True;
1048 }
1049 }
1050 else {
1051 indexinf++;
1052 }
1053 } while ((indexinf <= Nbpnts) && (!found));
1054
1055
1056 indexsup = indexinf +1;
1057 toutvu = (indexsup > Nbpnts);
1058 while (!toutvu) {
1059 paramsup = ((Nbpnts-indexsup)*Paramf + (indexsup-1)*Paraml)/(Nbpnts-1);
1060 Contap_HCurve2dTool::D1(thearc,paramsup,p2d,d2d);
1061 Adaptor3d_HSurfaceTool::D1(Surf,p2d.X(),p2d.Y(),pcour,d1u,d1v);
1062 tgt.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1063
1064 if (tgt.Magnitude() > gp::Resolution()) {
1065 if (TypeFunc == Contap_ContourPrs || TypeFunc==Contap_DraftPrs) {
1066 vecregard.SetXYZ(pcour.XYZ()-SFunc.Eye().XYZ());
1067 }
1068 vectest = vecregard.Crossed(tgt);
1069 }
1070 else {
1071 vectest = gp_Vec(0.,0.,0.);
1072 }
1073 if (vectest.Magnitude() <= gp::Resolution()) {
1074 // On cherche un vrai changement de signe
1075 indexsup++;
1076 }
1077 else {
1078 if (vectest.Dot(vecref) < 0.) {
1079 // Essayer de converger
1080 // cout << "Changement de signe detecte" << endl;
1081 solution = Standard_False;
1082 while (!solution) {
1083 paramp = (paraminf+paramsup)/2.;
1084 Contap_HCurve2dTool::D1(thearc,paramp,p2d,d2d);
1085 Adaptor3d_HSurfaceTool::D1(Surf,p2d.X(),p2d.Y(),pcour,d1u,d1v);
1086 tgt.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1087
1088 if (tgt.Magnitude() > gp::Resolution()) {
1089 if (TypeFunc == Contap_ContourPrs || TypeFunc==Contap_DraftPrs) {
1090 vecregard.SetXYZ(pcour.XYZ()-SFunc.Eye().XYZ());
1091 }
1092 vtestb = vecregard.Crossed(tgt);
1093 }
1094 else {
1095 vtestb = gp_Vec(0.,0.,0.);
1096 }
1097
1098 if ((vtestb.Magnitude() <= gp::Resolution())||
1099 (Abs(paramp-paraminf) <= toler) ||
1100 (Abs(paramp-paramsup) <= toler)) {
1101 // on est a la solution
1102 solution = Standard_True;
1103 ok = Standard_True;
1104 }
1105 else if (vtestb.Dot(vecref) < 0.) {
1106 paramsup = paramp;
1107 }
1108 else {
1109 paraminf = paramp;
1110 }
1111
1112 }
1113
1114 if (ok) {
1115 // On verifie que le point trouve ne correspond pas a un ou des
1116 // vertex deja existant(s). On teste sur le parametre paramp.
1117 for (i=1; i<=Line.NbVertex(); i++) {
1118 Contap_Point& thevtx = Line.Vertex(i);
1119 if (Abs(thevtx.ParameterOnLine()-paramp) <= toler) {
1120 thevtx.SetInternal();
1121 ok = Standard_False; // on a correspondance
1122 }
1123 }
1124 if (ok) { // il faut alors rajouter le point
1125 Contap_Point internalp(pcour,p2d.X(),p2d.Y());
1126 internalp.SetParameter(paramp);
1127 internalp.SetInternal();
1128 Line.Add(internalp);
1129 }
1130 }
1131 paramsup = ((Nbpnts-indexsup)*Paramf + (indexsup-1)*Paraml)/(Nbpnts-1);
1132 }
1133 vecref = vectest;
1134 indexinf = indexsup;
1135 indexsup++;
1136 paraminf = paramsup;
1137 }
1138 toutvu = (indexsup > Nbpnts);
1139 }
1140}
1141
1142
1143void ComputeInternalPoints
1144(Contap_Line& Line,
1145 Contap_SurfFunction& SFunc,
1146 const Standard_Real ureso,
1147 const Standard_Real vreso)
1148
1149{
1150 // On recherche les points ou la tangente a la ligne de contour et
1151 // la direction sont alignees.
1152 // 1ere etape : recheche de changement de signe.
1153 // 2eme etape : localisation de la solution par simili dichotomie
1154
1155
1156 Standard_Integer indexinf,indexsup,index;
1157 gp_Vec tgt, vecref, vectest, vtestb, vecregard;
1158 //gp_Pnt pprec,pcour;
1159 Standard_Boolean found,ok = Standard_False,toutvu,solution;
1160 Standard_Real paramp = 0.,U,V;
1161
1162 math_Vector XInf(1,2),XSup(1,2),X(1,2),F(1,1);
1163 math_Matrix DF(1,1,1,2);
1164 math_Vector toler(1,2),infb(1,2),supb(1,2);
1165
1166 if (Line.TypeContour() != Contap_Walking) {
1167 return;
1168 }
1169
1170 Standard_Integer Nbpnts = Line.NbPnts();
1171 const Handle(Adaptor3d_HSurface)& Surf = SFunc.Surface();
1172 Contap_TFunction TypeFunc(SFunc.FunctionType());
1173
1174 toler(1) = ureso; //-- Trop long !!! Adaptor3d_HSurfaceTool::UResolution(Surf,SFunc.Tolerance());
1175 toler(2) = vreso; //---Beaucoup trop long !!! Adaptor3d_HSurfaceTool::VResolution(Surf,SFunc.Tolerance());
1176 infb(1) = Adaptor3d_HSurfaceTool::FirstUParameter(Surf);
1177 infb(2) = Adaptor3d_HSurfaceTool::FirstVParameter(Surf);
1178 supb(1) = Adaptor3d_HSurfaceTool::LastUParameter(Surf);
1179 supb(2) = Adaptor3d_HSurfaceTool::LastVParameter(Surf);
1180
1181 math_FunctionSetRoot rsnld(SFunc,toler,30);
1182
1183 indexinf = 1;
1184 vecregard = SFunc.Direction();
1185
1186 found = Standard_False;
1187 do {
1188 Line.Point(indexinf).ParametersOnS2(XInf(1),XInf(2));
1189 SFunc.Values(XInf,F,DF);
1190 if (!SFunc.IsTangent()) {
1191 tgt = SFunc.Direction3d();
1192 if (TypeFunc == Contap_ContourPrs || TypeFunc == Contap_DraftPrs) {
1193 vecregard.SetXYZ(Line.Point(indexinf).Value().XYZ()-SFunc.Eye().XYZ());
1194 }
1195 vecref = vecregard.Crossed(tgt);
1196
1197 if (vecref.Magnitude() <= gp::Resolution()) {
1198 indexinf++;
1199 }
1200 else {
1201 found = Standard_True;
1202 }
1203 }
1204 else {
1205 indexinf++;
1206 }
1207 } while ((indexinf <= Nbpnts) && (!found));
1208
1209
1210 indexsup = indexinf +1;
1211 toutvu = (indexsup > Nbpnts);
1212 while (!toutvu) {
1213 Line.Point(indexsup).ParametersOnS2(XSup(1),XSup(2));
1214 SFunc.Values(XSup,F,DF);
1215 if (!SFunc.IsTangent()) {
1216 tgt = SFunc.Direction3d();
1217
1218 if (TypeFunc == Contap_ContourPrs || TypeFunc == Contap_DraftPrs) {
1219 vecregard.SetXYZ(Line.Point(indexsup).Value().XYZ()-SFunc.Eye().XYZ());
1220 }
1221 vectest = vecregard.Crossed(tgt);
1222 }
1223 else {
1224 vectest = gp_Vec(0.,0.,0.);
1225 }
1226 if (vectest.Magnitude() <= gp::Resolution()) {
1227 // On cherche un vrai changement de signe
1228 indexsup++;
1229 }
1230 else {
1231 if (vectest.Dot(vecref) < 0.) {
1232 // Essayer de converger
1233 // cout << "Changement de signe detecte" << endl;
1234 solution = Standard_False;
1235 while (!solution) {
1236 X(1) = (XInf(1) + XSup(1)) /2.;
1237 X(2) = (XInf(2) + XSup(2)) /2.;
1238 rsnld.Perform(SFunc,X,infb,supb);
1239
1240 if (!rsnld.IsDone()) {
1241 cout << "Echec recherche internal points" << endl;
1242 solution = Standard_True;
1243 ok = Standard_False;
1244 }
1245 else {
1246
1247 rsnld.Root(X);
1248 SFunc.Values(X,F,DF);
1249 if (Abs(F(1)) <= SFunc.Tolerance()) {
1250
1251 if (!SFunc.IsTangent()) {
1252 tgt = SFunc.Direction3d();
1253 if (TypeFunc == Contap_ContourPrs ||
1254 TypeFunc == Contap_DraftPrs) {
1255 vecregard.SetXYZ(SFunc.Point().XYZ()-SFunc.Eye().XYZ());
1256 }
1257 vtestb = vecregard.Crossed(tgt);
1258 }
1259 else {
1260 vtestb = gp_Vec(0.,0.,0.);
1261 }
1262 if ((vtestb.Magnitude() <= gp::Resolution())||
1263 (Abs(X(1)-XInf(1)) <= toler(1)
1264 && Abs(X(2)-XInf(2)) <= toler(2)) ||
1265 (Abs(X(1)-XSup(1)) <= toler(1)
1266 && Abs(X(2)-XSup(2)) <= toler(2))) {
1267 // on est a la solution
1268 solution = Standard_True;
1269 ok = Standard_True;
1270 }
1271 else if (vtestb.Dot(vecref) < 0.) {
1272 XSup = X;
1273 }
1274 else {
1275 XInf = X;
1276 }
1277 }
1278 else { // on n est pas sur une solution
1279 cout << "Echec recherche internal points" << endl;
1280 solution = Standard_True;
1281 ok = Standard_False;
1282 }
1283 }
1284 }
1285
1286 if (ok) {
1287 Standard_Boolean newpoint = Standard_False;
1288 Line.Point(indexinf).ParametersOnS2(U,V);
1289 gp_Vec2d vinf(X(1)-U,X(2)-V);
1290 if (Abs(vinf.X()) <= toler(1) && Abs(vinf.Y()) <= toler(2)) {
1291 paramp = indexinf;
1292 }
1293 else {
1294 for (index = indexinf+1; index <= indexsup; index++) {
1295 Line.Point(index).ParametersOnS2(U,V);
1296 gp_Vec2d vsup(X(1)-U,X(2)-V);
1297 if (Abs(vsup.X()) <= toler(1) && Abs(vsup.Y()) <= toler(2)) {
1298 paramp = index;
1299 break;
1300 }
1301 else if (vinf.Dot(vsup) < 0.) {
1302 // on est entre les 2 points
1303 paramp = index;
1304 IntSurf_PntOn2S pt2s;
1305 pt2s.SetValue(SFunc.Point(),Standard_False,X(1),X(2));
1306 Line.LineOn2S()->InsertBefore(index,pt2s);
1307
1308 //-- Il faut decaler les parametres des vertex situes entre
1309 //-- index et NbPnts ###################################
1310 for(Standard_Integer v=1; v<=Line.NbVertex(); v++) {
1311 Contap_Point& Vertex = Line.Vertex(v);
1312 if(Vertex.ParameterOnLine() >= index) {
1313 Vertex.SetParameter(Vertex.ParameterOnLine()+1);
1314 }
1315 }
1316
1317 Nbpnts = Nbpnts+1;
1318 indexsup = indexsup+1;
1319 newpoint = Standard_True;
1320 break;
1321 }
1322 else {
1323 vinf = vsup;
1324 }
1325 }
1326 }
1327
1328 Standard_Integer v;
1329 if (!newpoint) {
1330 // on est sur un point de cheminement. On regarde alors
1331 // la correspondance avec un vertex existant.
1332 newpoint = Standard_True;
1333 for (v=1; v<= Line.NbVertex(); v++) {
1334 Contap_Point& Vertex = Line.Vertex(v);
1335 if(Vertex.ParameterOnLine() == paramp) {
1336 Vertex.SetInternal();
1337 newpoint = Standard_False;
1338 }
1339 }
1340 }
1341
1342 if (newpoint && paramp >1. && paramp < Nbpnts) {
1343 // on doit creer un nouveau vertex.
1344 Contap_Point internalp(SFunc.Point(),X(1),X(2));
1345 internalp.SetParameter(paramp);
1346 internalp.SetInternal();
1347 Line.Add(internalp);
1348 }
1349 }
1350 Line.Point(indexsup).ParametersOnS2(XSup(1),XSup(2));
1351 }
1352 vecref = vectest;
1353 indexinf = indexsup;
1354 indexsup++;
1355 XInf = XSup;
1356 }
1357 toutvu = (indexsup > Nbpnts);
1358 }
1359}
1360
1361
1362void Contap_Contour::Perform
1363(const Handle(Adaptor3d_TopolTool)& Domain) {
1364
1365 done = Standard_False;
1366 slin.Clear();
1367
1368 Standard_Integer i,j,k,Nbvt1,Nbvt2,ivt1,ivt2;
1369 Standard_Integer NbPointRst,NbPointIns;
1370 Standard_Integer Nblines, Nbpts, indfirst, indlast;
1371 Standard_Real U,V;
1372 gp_Pnt2d pt2d;
1373 gp_Vec2d d2d;
1374 gp_Pnt ptonsurf;
1375 gp_Vec d1u,d1v,normale,tgtrst,tgline;
1376 Standard_Real currentparam;
1377 IntSurf_Transition TLine,TArc;
1378
1379 Contap_Line theline;
1380 Contap_Point ptdeb,ptfin;
1381 Contap_ThePathPointOfTheSearch PStartf,PStartl;
1382
1383 // Standard_Real TolArc = 1.e-5;
1384 Standard_Real TolArc = Precision::Confusion();
1385
1386 const Handle(Adaptor3d_HSurface)& Surf = mySFunc.Surface();
1387
1388 Standard_Real EpsU = Adaptor3d_HSurfaceTool::UResolution(Surf,Precision::Confusion());
1389 Standard_Real EpsV = Adaptor3d_HSurfaceTool::VResolution(Surf,Precision::Confusion());
1390 Standard_Real Preci = Min(EpsU,EpsV);
1391 // Standard_Real Fleche = 5.e-1;
1392 // Standard_Real Pas = 5.e-2;
1393 Standard_Real Fleche = 0.01;
1394 Standard_Real Pas = 0.005;
1395 // lbr: Il y avait Pas 0.2 -> Manque des Inters sur restr ; devrait faire un mini de 5 pts par lignes
1396 //-- le 23 janvier 98 0.05 -> 0.01
1397
1398
1399 //-- ******************************************************************************** Janvier 98
1400 Bnd_Box B1; Standard_Boolean Box1OK = Standard_True;
1401
1402 Standard_Real Uinf = Surf->FirstUParameter();
1403 Standard_Real Vinf = Surf->FirstVParameter();
1404 Standard_Real Usup = Surf->LastUParameter();
1405 Standard_Real Vsup = Surf->LastVParameter();
1406
1407 Standard_Boolean Uinfinfinite = Precision::IsNegativeInfinite(Uinf);
1408 Standard_Boolean Usupinfinite = Precision::IsPositiveInfinite(Usup);
1409 Standard_Boolean Vinfinfinite = Precision::IsNegativeInfinite(Vinf);
1410 Standard_Boolean Vsupinfinite = Precision::IsPositiveInfinite(Vsup);
1411
1412 if( Uinfinfinite || Usupinfinite || Vinfinfinite || Vsupinfinite) {
1413 Box1OK = Standard_False;
1414 }
1415 else {
1416 BndLib_AddSurface::Add(Surf->Surface(),1e-8,B1);
1417 }
1418 Standard_Real x0,y0,z0,x1,y1,z1,dx,dy,dz;
1419 if(Box1OK) {
1420 B1.Get(x0,y0,z0,x1,y1,z1);
1421 dx=x1-x0;
1422 dy=y1-y0;
1423 dz=z1-z0;
1424 }
1425 else {
1426 dx=dy=dz=1.0;
1427 }
1428 if(dx<dy) dx=dy;
1429 if(dx<dz) dx=dz;
1430 if(dx>10000.0) dx=10000.0;
1431 Fleche*=dx;
1432 TolArc*=dx;
1433 //-- ********************************************************************************
1434
1435
1436 //gp_Pnt valpt;
1437
1438 //jag 940616 SFunc.Set(1.e-8); // tolerance sur la fonction
1439 mySFunc.Set(Precision::Confusion()); // tolerance sur la fonction
1440
1441 Standard_Boolean RecheckOnRegularity = Standard_True;
1442 solrst.Perform(myAFunc,Domain,TolArc,TolArc,RecheckOnRegularity);
1443
1444 if (!solrst.IsDone()) {
1445 return;
1446 }
1447
1448 NbPointRst = solrst.NbPoints();
1449 IntSurf_SequenceOfPathPoint seqpdep;
1450 TColStd_Array1OfInteger Destination(1,NbPointRst+1);
1451 Destination.Init(0);
1452 if (NbPointRst != 0) {
1453 ComputeTangency(solrst,Domain,mySFunc,seqpdep,Destination);
1454 }
1455
1456 //jag 940616 solins.Perform(SFunc,Surf,Domain,1.e-6); // 1.e-6 : tolerance dans l espace.
1457 solins.Perform(mySFunc,Surf,Domain,Precision::Confusion());
1458
1459 NbPointIns = solins.NbPoints();
1460 IntSurf_SequenceOfInteriorPoint seqpins;
1461
1462 if (NbPointIns != 0) {
1463 Standard_Boolean bKeepAllPoints = Standard_False;
1464 //IFV begin
1465 if(solrst.NbSegments() <= 0) {
1466 if(mySFunc.FunctionType() == Contap_ContourStd) {
51740958 1467 const Handle(Adaptor3d_HSurface)& SurfToCheck = mySFunc.Surface();
1468 if(Adaptor3d_HSurfaceTool::GetType(SurfToCheck) == GeomAbs_Torus) {
1469 gp_Torus aTor = Adaptor3d_HSurfaceTool::Torus(SurfToCheck);
e2065c2f 1470 gp_Dir aTorDir = aTor.Axis().Direction();
1471 gp_Dir aProjDir = mySFunc.Direction();
1472
1473 if(aTorDir.Dot(aProjDir) < Precision::Confusion()) {
1474 bKeepAllPoints = Standard_True;
1475 }
1476 }
1477 }
1478 }
1479
1480 if(bKeepAllPoints) {
1481 Standard_Integer Nbp = solins.NbPoints(), indp;
1482 for (indp=1; indp <= Nbp; indp++) {
1483 const IntSurf_InteriorPoint& pti = solins.Value(indp);
1484 seqpins.Append(pti);
1485 }
1486 }
1487 //IFV - end
1488 else {
1489 KeepInsidePoints(solins,solrst,mySFunc,seqpins);
1490 }
1491 }
1492
1493 if (seqpdep.Length() != 0 || seqpins.Length() != 0) {
1494
1495 Contap_TheIWalking iwalk(Preci,Fleche,Pas);
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