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