0031642: Visualization - crash in Graphic3d_Structure::SetVisual() on redisplaying...
[occt.git] / src / GeometryTest / GeometryTest_CurveTanCommands.cxx
1 // Created on: 2017-06-16
2 // Created by: Natalia ERMOLAEVA
3 // Copyright (c) 2017 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <Draw.hxx>
17 #include <DrawTrSurf.hxx>
18 #include <Draw_Interpretor.hxx>
19 #include <GccAna_Circ2d3Tan.hxx>
20 #include <GccEnt.hxx>
21 #include <GccEnt_QualifiedLin.hxx>
22 #include <GccEnt_QualifiedCirc.hxx>
23 #include <Geom2d_Line.hxx>
24 #include <Geom2d_Circle.hxx>
25 #include <Geom2dAdaptor_Curve.hxx>
26 #include <GeometryTest.hxx>
27 #include <GeometryTest_DrawableQualifiedCurve2d.hxx>
28 #include <Precision.hxx>
29 #include <TCollection_AsciiString.hxx>
30 #include <stdio.h>
31
32 //=======================================================================
33 //function : qcircle
34 //purpose  : Parses command: "qcircle name x y radius [-unqualified|-enclosing|-enclosed|-outside|-noqualifier]"
35 //=======================================================================
36 static Standard_Integer qcurve (Draw_Interpretor&, Standard_Integer theArgsNb, const char** theArgVec)
37 {
38   if (theArgsNb < 5)
39   {
40     std::cout << "Error: wrong number of arguments.\n";
41     return 1;
42   }
43
44   Handle(Geom2d_Curve)  aResult2d;
45   TCollection_AsciiString aPositionType;
46   if (!strcmp (theArgVec[0], "qcircle"))
47   {
48     if (theArgsNb == 5 || theArgsNb == 6)
49       aResult2d = new Geom2d_Circle (gp_Ax22d (gp_Pnt2d (Draw::Atof (theArgVec[2]), Draw::Atof (theArgVec[3])),
50                                      gp_Dir2d (1,0)), Draw::Atof (theArgVec[4]));
51     else if (theArgsNb == 7 || theArgsNb == 8)
52       aResult2d = new Geom2d_Circle (gp_Ax22d (gp_Pnt2d (Draw::Atof (theArgVec[2]), Draw::Atof (theArgVec[3])),
53                   gp_Dir2d (Draw::Atof (theArgVec[4]), Draw::Atof (theArgVec[5]))), Draw::Atof (theArgVec[6]));
54
55     if (theArgsNb == 6)
56       aPositionType = theArgVec[5];
57     else if (theArgsNb == 8)
58       aPositionType = theArgVec[7];
59   }
60   else if(!strcmp (theArgVec[0], "qline"))
61   {
62     if (theArgsNb < 6)
63     {
64       std::cout << "Error: wrong number of arguments.\n";
65       return 1;
66     }
67     aResult2d = new Geom2d_Line (gp_Pnt2d (Draw::Atof (theArgVec[2]), Draw::Atof (theArgVec[3])),
68                                  gp_Dir2d (Draw::Atof (theArgVec[4]), Draw::Atof (theArgVec[5])));
69     if (theArgsNb == 7)
70       aPositionType = theArgVec[6];
71   }
72   else
73   {
74     std::cout << "Error: wrong command name.\n";
75     return 1;
76   }
77
78   GccEnt_Position aKindOfPosition = GccEnt_unqualified;
79   if (!aPositionType.IsEmpty())
80   {
81     GccEnt_Position aParameterPosition;
82     if (GccEnt::PositionFromString (aPositionType.ToCString(), aParameterPosition))
83       aKindOfPosition = aParameterPosition;
84   }
85
86   Draw::Set (theArgVec[1], new GeometryTest_DrawableQualifiedCurve2d (aResult2d, aKindOfPosition));
87   return 0;
88 }
89
90 //=======================================================================
91 //function : solutions
92 //purpose  : 
93 //=======================================================================
94 static Standard_Integer solutions (Draw_Interpretor& theDI, GccAna_Circ2d3Tan& theCirTan3, const char* theName)
95 {
96   if (!theCirTan3.IsDone())
97   {
98     std::cout << "GccAna_Circ2d3Tan is not done";
99     return 1;
100   }
101
102   TCollection_AsciiString aName = TCollection_AsciiString (theName) + "_";
103   GccEnt_Position aQualifier1, aQualifier2, aQualifier3;
104   Standard_Real aParSol, aParArg;
105   gp_Pnt2d aPntSol;
106   for (Standard_Integer aSolId = 1; aSolId <= theCirTan3.NbSolutions(); aSolId++)
107   {
108     Handle(Geom2d_Circle) aCircle = new Geom2d_Circle (theCirTan3.ThisSolution (aSolId));
109     TCollection_AsciiString aSolIdName = aName;
110     aSolIdName += TCollection_AsciiString (aSolId);
111     DrawTrSurf::Set (aSolIdName.ToCString(), aCircle);
112     theCirTan3.WhichQualifier (aSolId, aQualifier1, aQualifier2, aQualifier3);
113     theDI << "circle: " << aSolIdName.ToCString() << ", " << "qualifiers: " << GccEnt::PositionToString (aQualifier1)
114           << ", " << GccEnt::PositionToString (aQualifier2) << ", " << GccEnt::PositionToString (aQualifier3) << "\n";
115
116     theDI << "  tangent points: point (parameter on solution, parameter on argument)\n";
117     // the first tangent point
118     if (theCirTan3.IsTheSame1 (aSolId))
119       theDI << "    " << "= the solution number " << aSolId << " is equal to the first argument\n";
120     else
121     {
122       theCirTan3.Tangency1 (aSolId, aParSol, aParArg, aPntSol);
123       TCollection_AsciiString aTanPntIdName = aSolIdName + "_tp_1";
124       DrawTrSurf::Set (aTanPntIdName.ToCString(), aPntSol);
125       theDI << "    " << aTanPntIdName.ToCString() << " (" << aParSol << ", " << aParArg << ")\n";
126     }
127     // the second tangent point
128     if (theCirTan3.IsTheSame2 (aSolId))
129       theDI << "    " << "= the solution number " << aSolId << " is equal to the second argument\n";
130     else
131     {
132       theCirTan3.Tangency2 (aSolId, aParSol, aParArg, aPntSol);
133       TCollection_AsciiString aTanPntIdName = aSolIdName + "_tp_2";
134       DrawTrSurf::Set (aTanPntIdName.ToCString(), aPntSol);
135       theDI << "    " << aTanPntIdName.ToCString() << " (" << aParSol << ", " << aParArg << ")\n";
136     }
137     // the third tangent point
138     if (theCirTan3.IsTheSame3 (aSolId))
139       theDI << "    " << "= the solution number " << aSolId << " is equal to the third argument\n";
140     else
141     {
142       theCirTan3.Tangency3 (aSolId, aParSol, aParArg, aPntSol);
143       TCollection_AsciiString aTanPntIdName = aSolIdName + "_tp_3";
144       DrawTrSurf::Set (aTanPntIdName.ToCString(), aPntSol);
145       theDI << "    " << aTanPntIdName.ToCString() << " (" << aParSol << ", " << aParArg << ")";
146     }
147     if (aSolId != theCirTan3.NbSolutions())
148       theDI << "\n";
149   }
150   return 0;
151 }
152
153 //=======================================================================
154 //function : circ2d3Tan
155 //purpose  : Parses command: [circ2d3Tan cname qcicrle1/qlin1/point1 qcicrle2/qlin2/point2 qcicrle3/qlin3/point3
156 //                            tolerance]
157 //=======================================================================
158 static Standard_Integer circ2d3Tan (Draw_Interpretor& theDI, Standard_Integer theArgsNb, const char** theArgVec)
159 {
160   if (theArgsNb < 5)
161   {
162     std::cout << "Error: wrong number of arguments.\n";
163     return 1;
164   }
165
166   Handle(GeometryTest_DrawableQualifiedCurve2d) aQCurve1 =
167     Handle(GeometryTest_DrawableQualifiedCurve2d)::DownCast (Draw::Get (theArgVec[2]));
168   Handle(GeometryTest_DrawableQualifiedCurve2d) aQCurve2 =
169     Handle(GeometryTest_DrawableQualifiedCurve2d)::DownCast (Draw::Get (theArgVec[3]));
170   Handle(GeometryTest_DrawableQualifiedCurve2d) aQCurve3 =
171     Handle(GeometryTest_DrawableQualifiedCurve2d)::DownCast (Draw::Get (theArgVec[4]));
172
173   gp_Pnt2d aPoint1, aPoint2, aPoint3;
174   Standard_Boolean anIsPoint1 = DrawTrSurf::GetPoint2d (theArgVec[2], aPoint1);
175   Standard_Boolean anIsPoint2 = DrawTrSurf::GetPoint2d (theArgVec[3], aPoint2);
176   Standard_Boolean anIsPoint3 = DrawTrSurf::GetPoint2d (theArgVec[4], aPoint3);
177
178   Standard_Real aTolerance = Precision::Confusion();
179   if (theArgsNb > 5)
180     aTolerance = Draw::Atof (theArgVec[5]);
181
182   if (aQCurve1.IsNull()) // <point, point, point>
183   {
184     if (!anIsPoint1 || !anIsPoint2 || !anIsPoint3)
185     {
186       std::cout << "Error: wrong points definition.\n";
187       return 1;
188     }
189     GccAna_Circ2d3Tan aCircBuilder (aPoint1, aPoint2, aPoint3, aTolerance);
190     return solutions (theDI, aCircBuilder, theArgVec[1]);
191   }
192
193   // the first curve is not NULL
194   if (aQCurve2.IsNull()) // <qcircle, point, point> or <qlin, point, point>
195   {
196     if (!anIsPoint2 || !anIsPoint3)
197     {
198       std::cout << "Error: wrong points definition.\n";
199       return 1;
200     }
201     Geom2dAdaptor_Curve anAdaptorCurve1 (aQCurve1->GetCurve());
202     if (anAdaptorCurve1.GetType() == GeomAbs_Circle)
203     {
204       GccEnt_QualifiedCirc aQualifiedCircle1 (anAdaptorCurve1.Circle(), aQCurve1->GetPosition());
205       GccAna_Circ2d3Tan aCircBuilder (aQualifiedCircle1, aPoint2, aPoint3, aTolerance);
206       return solutions (theDI, aCircBuilder, theArgVec[1]);
207     }
208     else if (anAdaptorCurve1.GetType() == GeomAbs_Line)
209     {
210       GccEnt_QualifiedLin aQualifiedLin1 (anAdaptorCurve1.Line(), aQCurve1->GetPosition());
211       GccAna_Circ2d3Tan aCircBuilder (aQualifiedLin1, aPoint2, aPoint3, aTolerance);
212       return solutions (theDI, aCircBuilder, theArgVec[1]);
213     }
214     std::cout << "Error: wrong curve type.\n";
215     return 1;
216   }
217
218   // the first and the second curves are not NULL
219   if (aQCurve3.IsNull()) // <qcircle, qcircle, point> or <qcircle, qlin, point> or <qlin, qlin, point>
220   {
221     if (!anIsPoint3)
222     {
223       std::cout << "Error: wrong point definition.\n";
224       return 1;
225     }
226     Geom2dAdaptor_Curve anAdaptorCurve1 (aQCurve1->GetCurve());
227     Geom2dAdaptor_Curve anAdaptorCurve2 (aQCurve2->GetCurve());
228     if (anAdaptorCurve1.GetType() == GeomAbs_Circle && anAdaptorCurve2.GetType() == GeomAbs_Circle)
229     {
230       GccEnt_QualifiedCirc aQualifiedCircle1 (anAdaptorCurve1.Circle(), aQCurve1->GetPosition());
231       GccEnt_QualifiedCirc aQualifiedCircle2 (anAdaptorCurve2.Circle(), aQCurve2->GetPosition());
232       GccAna_Circ2d3Tan aCircBuilder (aQualifiedCircle1, aQualifiedCircle2, aPoint3, aTolerance);
233       return solutions (theDI, aCircBuilder, theArgVec[1]);
234     }
235     else if (anAdaptorCurve1.GetType() == GeomAbs_Circle && anAdaptorCurve2.GetType() == GeomAbs_Line)
236     {
237       GccEnt_QualifiedCirc aQualifiedCircle1 (anAdaptorCurve1.Circle(), aQCurve1->GetPosition());
238       GccEnt_QualifiedLin aQualifiedLin2 (anAdaptorCurve2.Line(), aQCurve2->GetPosition());
239       GccAna_Circ2d3Tan aCircBuilder (aQualifiedCircle1, aQualifiedLin2, aPoint3, aTolerance);
240       return solutions (theDI, aCircBuilder, theArgVec[1]);
241     }
242     else if (anAdaptorCurve1.GetType() == GeomAbs_Line && anAdaptorCurve2.GetType() == GeomAbs_Line)
243     {
244       GccEnt_QualifiedLin aQualifiedLin1 (anAdaptorCurve1.Line(), aQCurve1->GetPosition());
245       GccEnt_QualifiedLin aQualifiedLin2 (anAdaptorCurve2.Line(), aQCurve2->GetPosition());
246       GccAna_Circ2d3Tan aCircBuilder (aQualifiedLin1, aQualifiedLin2, aPoint3, aTolerance);
247       return solutions (theDI, aCircBuilder, theArgVec[1]);
248     }
249     std::cout << "Error: wrong curve type.\n";
250     return 1;
251   }
252
253   // the first, the second and the third curves are not NULL
254   // <qcircle, qcircle, qcircle> or <qcircle, qcircle, qlin>, <qcircle, qlin, qlin>, <qlin, qlin, qlin>
255   Geom2dAdaptor_Curve anAdaptorCurve1 (aQCurve1->GetCurve());
256   Geom2dAdaptor_Curve anAdaptorCurve2 (aQCurve2->GetCurve());
257   Geom2dAdaptor_Curve anAdaptorCurve3 (aQCurve3->GetCurve());
258   if (anAdaptorCurve1.GetType() == GeomAbs_Circle && anAdaptorCurve2.GetType() == GeomAbs_Circle &&
259       anAdaptorCurve3.GetType() == GeomAbs_Circle)
260   {
261     GccEnt_QualifiedCirc aQualifiedCircle1 (anAdaptorCurve1.Circle(), aQCurve1->GetPosition());
262     GccEnt_QualifiedCirc aQualifiedCircle2 (anAdaptorCurve2.Circle(), aQCurve2->GetPosition());
263     GccEnt_QualifiedCirc aQualifiedCircle3 (anAdaptorCurve3.Circle(), aQCurve3->GetPosition());
264     GccAna_Circ2d3Tan aCircBuilder (aQualifiedCircle1, aQualifiedCircle2, aQualifiedCircle3, aTolerance);
265     return solutions (theDI, aCircBuilder, theArgVec[1]);
266   }
267   if (anAdaptorCurve1.GetType() == GeomAbs_Circle && anAdaptorCurve2.GetType() == GeomAbs_Circle &&
268       anAdaptorCurve3.GetType() == GeomAbs_Line)
269   {
270     GccEnt_QualifiedCirc aQualifiedCircle1 (anAdaptorCurve1.Circle(), aQCurve1->GetPosition());
271     GccEnt_QualifiedCirc aQualifiedCircle2 (anAdaptorCurve2.Circle(), aQCurve2->GetPosition());
272     GccEnt_QualifiedLin aQualifiedLin3 (anAdaptorCurve3.Line(), aQCurve3->GetPosition());
273     GccAna_Circ2d3Tan aCircBuilder (aQualifiedCircle1, aQualifiedCircle2, aQualifiedLin3, aTolerance);
274     return solutions (theDI, aCircBuilder, theArgVec[1]);
275   }
276   if (anAdaptorCurve1.GetType() == GeomAbs_Circle && anAdaptorCurve2.GetType() == GeomAbs_Line &&
277       anAdaptorCurve3.GetType() == GeomAbs_Line)
278   {
279     GccEnt_QualifiedCirc aQualifiedCircle1 (anAdaptorCurve1.Circle(), aQCurve1->GetPosition());
280     GccEnt_QualifiedLin aQualifiedLin2 (anAdaptorCurve2.Line(), aQCurve2->GetPosition());
281     GccEnt_QualifiedLin aQualifiedLin3 (anAdaptorCurve3.Line(), aQCurve3->GetPosition());
282     GccAna_Circ2d3Tan aCircBuilder (aQualifiedCircle1, aQualifiedLin2, aQualifiedLin3, aTolerance);
283     return solutions (theDI, aCircBuilder, theArgVec[1]);
284   }
285   if (anAdaptorCurve1.GetType() == GeomAbs_Line && anAdaptorCurve2.GetType() == GeomAbs_Line &&
286       anAdaptorCurve3.GetType() == GeomAbs_Line)
287   {
288     GccEnt_QualifiedLin aQualifiedLin1 (anAdaptorCurve1.Line(), aQCurve1->GetPosition());
289     GccEnt_QualifiedLin aQualifiedLin2 (anAdaptorCurve2.Line(), aQCurve2->GetPosition());
290     GccEnt_QualifiedLin aQualifiedLin3 (anAdaptorCurve3.Line(), aQCurve3->GetPosition());
291     GccAna_Circ2d3Tan aCircBuilder (aQualifiedLin1, aQualifiedLin2, aQualifiedLin3, aTolerance);
292     return solutions (theDI, aCircBuilder, theArgVec[1]);
293   }
294
295   std::cout << "Error: wrong curve type.\n";
296   return 1;
297 }
298
299 //=======================================================================
300 //function : CurveTanCommands
301 //purpose  : 
302 //=======================================================================
303 void  GeometryTest::CurveTanCommands (Draw_Interpretor& theCommands)
304 {
305   static Standard_Boolean aLoaded = Standard_False;
306   if (aLoaded) return;
307   aLoaded = Standard_True;
308   
309   DrawTrSurf::BasicCommands (theCommands);
310   
311   const char* aGroup;
312   aGroup = "GEOMETRY tangent curves creation";
313
314   theCommands.Add ("qcircle",
315             "qcircle name {x y [ux uy] radius} [-unqualified|-enclosing|-enclosed|-outside|-noqualifier]"
316     "\n\t\t: Creates qualified circle.",
317    __FILE__, qcurve, aGroup);
318
319   theCommands.Add ("qline",
320             "qline name x y dx dy [-unqualified|-enclosing|-enclosed|-outside|-noqualifier]"
321     "\n\t\t: Creates qualified line.",
322     __FILE__, qcurve, aGroup);
323
324   theCommands.Add ("circ2d3Tan",
325             "circ2d3Tan cname {qcicrle1|qlin1|point1} {qcicrle2|qlin2|point2} {qcicrle3|qlin3|point3} [tolerance]"
326     "\n\t\t: Creates 2d circles tangent to 3 arguments. The arguments are points, lines or circles."
327     "\n\t\t: Possible arguments combinations:"
328     "\n\t\t:            <qcircle, qcircle, qcircle>,"
329     "\n\t\t:            <qcircle, qcircle, qlin>,"
330     "\n\t\t:            <qcircle, qcircle, point>,"
331     "\n\t\t:            <qcircle, qlin, qlin>,"
332     "\n\t\t:            <qcircle, qlin, point>,"
333     "\n\t\t:            <qcircle, qlin, qlin>,"
334     "\n\t\t:            <qcircle, point, point>,"
335     "\n\t\t:            <qlin, qlin, qlin>,"
336     "\n\t\t:            <qlin, qlin, point>,"
337     "\n\t\t:            <qlin, point, point>,"
338     "\n\t\t:            <point, point, point>.",
339     __FILE__, circ2d3Tan, aGroup);
340 }