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