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