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