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