b311480e |
1 | // Created on: 1995-01-17 |
2 | // Created by: Remi LEQUETTE |
3 | // Copyright (c) 1995-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 | |
23 | #include <Geom_Curve.hxx> |
24 | #include <Geom_Surface.hxx> |
25 | #include <Draw.hxx> |
26 | #include <Draw_Interpretor.hxx> |
27 | #include <DrawTrSurf.hxx> |
28 | #include <Draw_Appli.hxx> |
29 | #include <GeometryTest.hxx> |
30 | #include <GeomAPI_ProjectPointOnCurve.hxx> |
31 | #include <GeomAPI_ProjectPointOnSurf.hxx> |
32 | #include <GeomAPI_ExtremaCurveCurve.hxx> |
33 | #include <GeomAPI_ExtremaCurveSurface.hxx> |
34 | #include <GeomAPI_ExtremaSurfaceSurface.hxx> |
35 | #include <GeomAPI_PointsToBSpline.hxx> |
36 | #include <GeomAPI_PointsToBSplineSurface.hxx> |
37 | #include <Geom_Line.hxx> |
38 | #include <Geom_TrimmedCurve.hxx> |
39 | #include <Draw_Segment3D.hxx> |
40 | #include <Draw_Marker3D.hxx> |
41 | #include <Draw_Color.hxx> |
42 | #include <Draw_MarkerShape.hxx> |
43 | #include <TColgp_Array1OfPnt.hxx> |
44 | #include <TColgp_Array2OfPnt.hxx> |
45 | #include <TColStd_Array2OfReal.hxx> |
46 | #include <Precision.hxx> |
47 | #include <stdio.h> |
48 | #ifdef WNT |
49 | Standard_IMPORT Draw_Viewer dout; |
50 | #endif |
51 | |
52 | //======================================================================= |
53 | //function : proj |
54 | //purpose : |
55 | //======================================================================= |
56 | |
57 | static Standard_Integer proj (Draw_Interpretor& di, Standard_Integer n, const char** a) |
58 | { |
569aff1e |
59 | if ( n < 5) |
60 | { |
61 | cout << " Use proj curve/surf x y z [extrema algo: g(grad)/t(tree)]" << endl; |
62 | return 1; |
63 | } |
7fd59977 |
64 | |
91322f44 |
65 | gp_Pnt P(Draw::Atof(a[2]),Draw::Atof(a[3]),Draw::Atof(a[4])); |
7fd59977 |
66 | |
67 | char name[100]; |
68 | |
69 | Handle(Geom_Curve) GC = DrawTrSurf::GetCurve(a[1]); |
70 | Handle(Geom_Surface) GS; |
569aff1e |
71 | Extrema_ExtAlgo aProjAlgo = Extrema_ExtAlgo_Grad; |
72 | if (n == 6 && a[5][0] == 't') |
73 | aProjAlgo = Extrema_ExtAlgo_Tree; |
7fd59977 |
74 | |
75 | if (GC.IsNull()) { |
76 | GS = DrawTrSurf::GetSurface(a[1]); |
77 | if (GS.IsNull()) |
78 | return 1; |
79 | Standard_Real U1, U2, V1, V2; |
80 | GS->Bounds(U1,U2,V1,V2); |
81 | |
569aff1e |
82 | GeomAPI_ProjectPointOnSurf proj(P,GS,U1,U2,V1,V2,aProjAlgo); |
7fd59977 |
83 | Standard_Real UU,VV; |
84 | for ( Standard_Integer i = 1; i <= proj.NbPoints(); i++) { |
85 | gp_Pnt P1 = proj.Point(i); |
86 | if ( P.Distance(P1) > Precision::Confusion()) { |
87 | Handle(Geom_Line) L = new Geom_Line(P,gp_Vec(P,P1)); |
88 | Handle(Geom_TrimmedCurve) CT = |
89 | new Geom_TrimmedCurve(L, 0., P.Distance(P1)); |
91322f44 |
90 | Sprintf(name,"%s%d","ext_",i); |
7fd59977 |
91 | char* temp = name; // portage WNT |
92 | DrawTrSurf::Set(temp, CT); |
93 | di << name << " "; |
94 | } |
95 | else { |
91322f44 |
96 | Sprintf(name,"%s%d","ext_",i); |
7fd59977 |
97 | di << name << " "; |
98 | char* temp = name; // portage WNT |
99 | DrawTrSurf::Set(temp, P1); |
100 | proj.Parameters(i,UU,VV); |
101 | di << " Le point est sur la surface." << "\n"; |
102 | di << " Ses parametres sont: UU = " << UU << "\n"; |
103 | di << " VV = " << VV << "\n"; |
104 | } |
105 | } |
106 | |
107 | } |
108 | else { |
109 | GeomAPI_ProjectPointOnCurve proj(P,GC,GC->FirstParameter(), |
110 | GC->LastParameter()); |
111 | // Standard_Real UU; |
112 | for ( Standard_Integer i = 1; i <= proj.NbPoints(); i++) { |
113 | gp_Pnt P1 = proj.Point(i); |
114 | Standard_Real UU = proj.Parameter(i); |
115 | di << " parameter " << i << " = " << UU << "\n"; |
116 | if ( P.Distance(P1) > Precision::Confusion()) { |
117 | Handle(Geom_Line) L = new Geom_Line(P,gp_Vec(P,P1)); |
118 | Handle(Geom_TrimmedCurve) CT = |
119 | new Geom_TrimmedCurve(L, 0., P.Distance(P1)); |
91322f44 |
120 | Sprintf(name,"%s%d","ext_",i); |
7fd59977 |
121 | char* temp = name; // portage WNT |
122 | DrawTrSurf::Set(temp, CT); |
123 | di << name << " "; |
124 | } |
125 | else { |
91322f44 |
126 | Sprintf(name,"%s%d","ext_",i); |
7fd59977 |
127 | char* temp = name; // portage WNT |
128 | DrawTrSurf::Set(temp, P1); |
129 | di << name << " "; |
130 | UU = proj.Parameter(i); |
131 | di << " Le point est sur la courbe." << "\n"; |
132 | di << " Son parametre est U = " << UU << "\n"; |
133 | } |
134 | } |
135 | } |
136 | return 0; |
137 | } |
138 | |
139 | //======================================================================= |
140 | //function : appro |
141 | //purpose : |
142 | //======================================================================= |
143 | |
144 | static Standard_Integer appro(Draw_Interpretor& di, Standard_Integer n, const char** a) |
145 | { |
146 | if ( n<3) return 1; |
147 | |
148 | Handle(Geom_Curve) GC; |
91322f44 |
149 | Standard_Integer Nb = Draw::Atoi(a[2]); |
7fd59977 |
150 | |
151 | TColgp_Array1OfPnt Points(1, Nb); |
152 | |
153 | Handle(Draw_Marker3D) mark; |
154 | |
155 | if ( n == 4) { |
156 | GC = DrawTrSurf::GetCurve(a[3]); |
157 | if ( GC.IsNull()) |
158 | return 1; |
159 | |
160 | Standard_Real U, U1, U2; |
161 | U1 = GC->FirstParameter(); |
162 | U2 = GC->LastParameter(); |
163 | Standard_Real Delta = ( U2 - U1) / (Nb-1); |
164 | for ( Standard_Integer i = 1 ; i <= Nb; i++) { |
165 | U = U1 + (i-1) * Delta; |
166 | Points(i) = GC->Value(U); |
167 | mark = new Draw_Marker3D( Points(i), Draw_X, Draw_vert); |
168 | dout << mark; |
169 | } |
170 | } |
171 | else { |
172 | Standard_Integer id,XX,YY,b; |
173 | dout.Select(id,XX,YY,b); |
174 | Standard_Real zoom = dout.Zoom(id); |
175 | |
176 | Points(1) = gp_Pnt( ((Standard_Real)XX)/zoom, |
177 | ((Standard_Real)YY)/zoom, |
178 | 0.); |
179 | |
180 | mark = new Draw_Marker3D( Points(1), Draw_X, Draw_vert); |
181 | |
182 | dout << mark; |
183 | |
184 | for (Standard_Integer i = 2; i<=Nb; i++) { |
185 | dout.Select(id,XX,YY,b); |
186 | Points(i) = gp_Pnt( ((Standard_Real)XX)/zoom, |
187 | ((Standard_Real)YY)/zoom, |
188 | 0.); |
189 | mark = new Draw_Marker3D( Points(i), Draw_X, Draw_vert); |
190 | dout << mark; |
191 | } |
192 | } |
193 | dout.Flush(); |
194 | Standard_Integer Dmin = 3; |
195 | Standard_Integer Dmax = 8; |
196 | Standard_Real Tol3d = 1.e-3; |
197 | |
198 | Handle(Geom_BSplineCurve) TheCurve; |
199 | GeomAPI_PointsToBSpline aPointToBSpline(Points,Dmin,Dmax,GeomAbs_C2,Tol3d); |
200 | TheCurve = aPointToBSpline.Curve(); |
201 | |
202 | |
203 | DrawTrSurf::Set(a[1], TheCurve); |
204 | di << a[1]; |
205 | |
206 | return 0; |
207 | |
208 | } |
209 | |
210 | |
211 | //======================================================================= |
212 | //function : grilapp |
213 | //purpose : |
214 | //======================================================================= |
215 | |
216 | static Standard_Integer grilapp(Draw_Interpretor& di, Standard_Integer n, const char** a) |
217 | { |
218 | if ( n < 12) return 1; |
219 | |
220 | Standard_Integer i,j; |
91322f44 |
221 | Standard_Integer Nu = Draw::Atoi(a[2]); |
222 | Standard_Integer Nv = Draw::Atoi(a[3]); |
7fd59977 |
223 | TColStd_Array2OfReal ZPoints (1, Nu, 1, Nv); |
224 | |
91322f44 |
225 | Standard_Real X0 = Draw::Atof(a[4]); |
226 | Standard_Real dX = Draw::Atof(a[5]); |
227 | Standard_Real Y0 = Draw::Atof(a[6]); |
228 | Standard_Real dY = Draw::Atof(a[7]); |
7fd59977 |
229 | |
230 | Standard_Integer Count = 8; |
231 | for ( j = 1; j <= Nv; j++) { |
232 | for ( i = 1; i <= Nu; i++) { |
233 | if ( Count > n) return 1; |
91322f44 |
234 | ZPoints(i,j) = Draw::Atof(a[Count]); |
7fd59977 |
235 | Count++; |
236 | } |
237 | } |
238 | |
239 | Handle(Geom_BSplineSurface) S |
240 | = GeomAPI_PointsToBSplineSurface(ZPoints,X0,dX,Y0,dY); |
241 | DrawTrSurf::Set(a[1],S); |
242 | |
243 | di << a[1]; |
244 | |
245 | return 0; |
246 | } |
247 | |
248 | //======================================================================= |
249 | //function : surfapp |
250 | //purpose : |
251 | //======================================================================= |
252 | |
253 | static Standard_Integer surfapp(Draw_Interpretor& di, Standard_Integer n, const char** a) |
254 | { |
255 | if ( n < 5 ) return 1; |
256 | |
257 | Standard_Integer i,j; |
91322f44 |
258 | Standard_Integer Nu = Draw::Atoi(a[2]); |
259 | Standard_Integer Nv = Draw::Atoi(a[3]); |
7fd59977 |
260 | TColgp_Array2OfPnt Points (1, Nu, 1, Nv); |
261 | |
262 | if ( n == 5) { |
263 | Handle(Geom_Surface) Surf = DrawTrSurf::GetSurface(a[4]); |
264 | if ( Surf.IsNull()) return 1; |
265 | |
266 | Standard_Real U, V, U1, V1, U2, V2; |
267 | Surf->Bounds( U1, U2, V1, V2); |
268 | for ( j = 1; j <= Nv; j++) { |
269 | V = V1 + (j-1) * (V2-V1) / (Nv-1); |
270 | for ( i = 1; i <= Nu; i++) { |
271 | U = U1 + (i-1) * (U2-U1) / (Nu-1); |
272 | Points(i,j) = Surf->Value(U,V); |
273 | } |
274 | } |
275 | } |
276 | else if ( n >= 16) { |
277 | Standard_Integer Count = 4; |
278 | for ( j = 1; j <= Nv; j++) { |
279 | for ( i = 1; i <= Nu; i++) { |
280 | if ( Count > n) return 1; |
91322f44 |
281 | Points(i,j) = gp_Pnt(Draw::Atof(a[Count]),Draw::Atof(a[Count+1]),Draw::Atof(a[Count+2])); |
7fd59977 |
282 | Count += 3; |
283 | } |
284 | } |
285 | } |
286 | char name[100]; |
287 | Standard_Integer Count = 1; |
288 | for ( j = 1; j <= Nv; j++) { |
289 | for ( i = 1; i <= Nu; i++) { |
91322f44 |
290 | Sprintf(name,"point_%d",Count++); |
7fd59977 |
291 | char* temp = name; // portage WNT |
292 | DrawTrSurf::Set(temp,Points(i,j)); |
293 | } |
294 | } |
295 | |
296 | Handle(Geom_BSplineSurface) S = GeomAPI_PointsToBSplineSurface(Points); |
297 | DrawTrSurf::Set(a[1],S); |
298 | di << a[1]; |
299 | |
300 | return 0; |
301 | } |
302 | |
303 | |
304 | //======================================================================= |
305 | //function : extrema |
306 | //purpose : |
307 | //======================================================================= |
308 | |
309 | static Standard_Integer extrema(Draw_Interpretor& di, Standard_Integer n, const char** a) |
310 | { |
311 | if ( n<3) return 1; |
312 | |
313 | Handle(Geom_Curve) GC1, GC2; |
314 | Handle(Geom_Surface) GS1, GS2; |
315 | |
316 | Standard_Boolean C1 = Standard_False; |
317 | Standard_Boolean C2 = Standard_False; |
318 | Standard_Boolean S1 = Standard_False; |
319 | Standard_Boolean S2 = Standard_False; |
320 | |
321 | Standard_Real U1f,U1l,U2f,U2l,V1f,V1l,V2f,V2l; |
322 | |
323 | GC1 = DrawTrSurf::GetCurve(a[1]); |
324 | if ( GC1.IsNull()) { |
325 | GS1 = DrawTrSurf::GetSurface(a[1]); |
326 | if ( GS1.IsNull()) |
327 | return 1; |
328 | S1 = Standard_True; |
329 | GS1->Bounds(U1f,U1l,V1f,V1l); |
330 | } |
331 | else { |
332 | C1 = Standard_True; |
333 | U1f = GC1->FirstParameter(); |
334 | U1l = GC1->LastParameter(); |
335 | } |
336 | |
337 | GC2 = DrawTrSurf::GetCurve(a[2]); |
338 | if ( GC2.IsNull()) { |
339 | GS2 = DrawTrSurf::GetSurface(a[2]); |
340 | if ( GS2.IsNull()) |
341 | return 1; |
342 | S2 = Standard_True; |
343 | GS2->Bounds(U2f,U2l,V2f,V2l); |
344 | } |
345 | else { |
346 | C2 = Standard_True; |
347 | U2f = GC2->FirstParameter(); |
348 | U2l = GC2->LastParameter(); |
349 | } |
350 | |
351 | char name[100]; |
352 | if ( C1 && C2) { |
353 | GeomAPI_ExtremaCurveCurve Ex(GC1,GC2,U1f,U1l,U2f,U2l); |
354 | if(!Ex.Extrema().IsParallel()) { |
355 | for ( Standard_Integer i = 1; i <= Ex.NbExtrema(); i++) { |
356 | gp_Pnt P1,P2; |
357 | Ex.Points(i,P1,P2); |
358 | if (P1.Distance(P2) < 1.e-16) { |
359 | di << "Extrema " << i << " is point : " << P1.X() << " " << P1.Y() << " " << P1.Z() << "\n"; |
360 | continue; |
361 | } |
362 | Handle(Geom_Line) L = new Geom_Line(P1,gp_Vec(P1,P2)); |
363 | Handle(Geom_TrimmedCurve) CT = |
364 | new Geom_TrimmedCurve(L, 0., P1.Distance(P2)); |
91322f44 |
365 | Sprintf(name,"%s%d","ext_",i); |
7fd59977 |
366 | char* temp = name; // portage WNT |
367 | DrawTrSurf::Set(temp, CT); |
368 | di << name << " "; |
369 | } |
370 | } |
371 | else { |
372 | di << "Infinite number of extremas, distance = " << Ex.LowerDistance() << "\n"; |
373 | } |
374 | } |
375 | else if ( C1 & S2) { |
376 | GeomAPI_ExtremaCurveSurface Ex(GC1,GS2,U1f,U1l,U2f,U2l,V2f,V2l); |
377 | for ( Standard_Integer i = 1; i <= Ex.NbExtrema(); i++) { |
378 | gp_Pnt P1,P2; |
379 | Ex.Points(i,P1,P2); |
380 | if (P1.Distance(P2) < 1.e-16) continue; |
381 | Handle(Geom_Line) L = new Geom_Line(P1,gp_Vec(P1,P2)); |
382 | Handle(Geom_TrimmedCurve) CT = |
383 | new Geom_TrimmedCurve(L, 0., P1.Distance(P2)); |
91322f44 |
384 | Sprintf(name,"%s%d","ext_",i); |
7fd59977 |
385 | char* temp = name; // portage WNT |
386 | DrawTrSurf::Set(temp, CT); |
387 | di << name << " "; |
388 | } |
389 | } |
390 | else if ( S1 & C2) { |
391 | GeomAPI_ExtremaCurveSurface Ex(GC2,GS1,U2f,U2l,U1f,U1l,V1f,V1l); |
392 | for ( Standard_Integer i = 1; i <= Ex.NbExtrema(); i++) { |
393 | gp_Pnt P1,P2; |
394 | Ex.Points(i,P1,P2); |
395 | if (P1.Distance(P2) < 1.e-16) continue; |
396 | Handle(Geom_Line) L = new Geom_Line(P1,gp_Vec(P1,P2)); |
397 | Handle(Geom_TrimmedCurve) CT = |
398 | new Geom_TrimmedCurve(L, 0., P1.Distance(P2)); |
91322f44 |
399 | Sprintf(name,"%s%d","ext_",i); |
7fd59977 |
400 | char* temp = name; // portage WNT |
401 | DrawTrSurf::Set(temp, CT); |
402 | di << name << " "; |
403 | } |
404 | } |
405 | else if ( S1 & S2) { |
406 | GeomAPI_ExtremaSurfaceSurface Ex(GS1,GS2,U1f,U1l,V1f,V1l,U2f,U2l,V2f,V2l); |
407 | for ( Standard_Integer i = 1; i <= Ex.NbExtrema(); i++) { |
408 | gp_Pnt P1,P2; |
409 | Ex.Points(i,P1,P2); |
410 | if (P1.Distance(P2) < 1.e-16) continue; |
411 | Handle(Geom_Line) L = new Geom_Line(P1,gp_Vec(P1,P2)); |
412 | Handle(Geom_TrimmedCurve) CT = |
413 | new Geom_TrimmedCurve(L, 0., P1.Distance(P2)); |
91322f44 |
414 | Sprintf(name,"%s%d","ext_",i); |
7fd59977 |
415 | char* temp = name; // portage WNT |
416 | DrawTrSurf::Set(temp, CT); |
417 | di << name << " "; |
418 | } |
419 | } |
420 | |
421 | return 0; |
422 | |
423 | } |
424 | |
425 | //======================================================================= |
426 | //function : totalextcc |
427 | //purpose : |
428 | //======================================================================= |
429 | |
430 | static Standard_Integer totalextcc(Draw_Interpretor& di, Standard_Integer n, const char** a) |
431 | { |
432 | if ( n<3) return 1; |
433 | |
434 | Handle(Geom_Curve) GC1, GC2; |
435 | |
436 | |
437 | Standard_Real U1f,U1l,U2f,U2l; |
438 | |
439 | GC1 = DrawTrSurf::GetCurve(a[1]); |
440 | if ( GC1.IsNull()) { |
441 | return 1; |
442 | } |
443 | else { |
444 | U1f = GC1->FirstParameter(); |
445 | U1l = GC1->LastParameter(); |
446 | } |
447 | |
448 | GC2 = DrawTrSurf::GetCurve(a[2]); |
449 | if ( GC2.IsNull()) { |
450 | return 1; |
451 | } |
452 | else { |
453 | U2f = GC2->FirstParameter(); |
454 | U2l = GC2->LastParameter(); |
455 | } |
456 | |
457 | char name[100]; |
458 | GeomAPI_ExtremaCurveCurve Ex(GC1,GC2,U1f,U1l,U2f,U2l); |
459 | gp_Pnt P1,P2; |
460 | if(Ex.TotalNearestPoints(P1,P2)) { |
461 | if (P1.Distance(P2) < 1.e-16) { |
462 | di << "Extrema is point : " << P1.X() << " " << P1.Y() << " " << P1.Z() << "\n"; |
463 | } |
464 | else { |
465 | di << "Extrema is segment of line" << "\n"; |
466 | Handle(Geom_Line) L = new Geom_Line(P1,gp_Vec(P1,P2)); |
467 | Handle(Geom_TrimmedCurve) CT = |
468 | new Geom_TrimmedCurve(L, 0., P1.Distance(P2)); |
91322f44 |
469 | Sprintf(name,"%s%d","ext_",1); |
7fd59977 |
470 | char* temp = name; // portage WNT |
471 | DrawTrSurf::Set(temp, CT); |
472 | di << name << " "; |
473 | } |
474 | |
475 | Standard_Real u1, u2; |
476 | Ex.TotalLowerDistanceParameters(u1, u2); |
477 | |
478 | di << "Parameters on curves : " << u1 << " " << u2 << "\n"; |
479 | |
480 | } |
481 | else { |
482 | di << "Curves are infinite and parallel" << "\n"; |
483 | } |
484 | |
485 | di << "Minimal distance : " << Ex.TotalLowerDistance() << "\n"; |
486 | |
487 | return 0; |
488 | |
489 | } |
490 | |
491 | |
492 | void GeometryTest::APICommands(Draw_Interpretor& theCommands) |
493 | { |
494 | static Standard_Boolean done = Standard_False; |
495 | if (done) return; |
496 | |
497 | done = Standard_True; |
498 | const char* g; |
499 | |
500 | g = "GEOMETRY curves and surfaces analysis"; |
501 | |
569aff1e |
502 | theCommands.Add("proj", "proj curve/surf x y z [extrema algo: g(grad)/t(tree)]",__FILE__, proj); |
7fd59977 |
503 | |
504 | g = "GEOMETRY approximations"; |
505 | |
506 | theCommands.Add("appro", "appro result nbpoint [curve]",__FILE__, appro); |
507 | theCommands.Add("surfapp","surfapp result nbupoint nbvpoint x y z ....", |
508 | __FILE__, |
509 | surfapp); |
510 | theCommands.Add("grilapp", |
511 | "grilapp result nbupoint nbvpoint X0 dX Y0 dY z11 z12 .. z1nu .... ", |
512 | __FILE__,grilapp); |
513 | |
514 | g = "GEOMETRY curves and surfaces analysis"; |
515 | |
516 | theCommands.Add("extrema", "extrema curve/surface curve/surface",__FILE__,extrema); |
517 | theCommands.Add("totalextcc", "totalextcc curve curve",__FILE__,totalextcc); |
518 | } |