Salome HOME
b545e3c4880c24aa142d8b73d08a37b87f4a3543
[modules/geom.git] / src / GEOMImpl / GEOMImpl_ICurvesOperations.cxx
1 // Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #ifdef WNT
24 // E.A. : On windows with python 2.6, there is a conflict
25 // E.A. : between pymath.h and Standard_math.h which define
26 // E.A. : some same symbols : acosh, asinh, ...
27 #include <Standard_math.hxx>
28 #include <pymath.h>
29 #endif
30
31 #include <Python.h>
32 #include <structmember.h>
33
34 #ifdef HAVE_FINITE
35 #undef HAVE_FINITE
36 #endif
37 #include <Standard_Stream.hxx>
38
39 #include <GEOMImpl_ICurvesOperations.hxx>
40
41 #include <TColStd_HArray1OfReal.hxx>
42
43 #include <GEOM_Function.hxx>
44 #include <GEOM_PythonDump.hxx>
45
46 #include <GEOMImpl_Types.hxx>
47
48 #include <GEOMImpl_PolylineDriver.hxx>
49 #include <GEOMImpl_CircleDriver.hxx>
50 #include <GEOMImpl_SplineDriver.hxx>
51 #include <GEOMImpl_EllipseDriver.hxx>
52 #include <GEOMImpl_ArcDriver.hxx>
53 #include <GEOMImpl_SketcherDriver.hxx>
54 #include <GEOMImpl_3DSketcherDriver.hxx>
55
56 #include <GEOMImpl_IPolyline.hxx>
57 #include <GEOMImpl_ICircle.hxx>
58 #include <GEOMImpl_ISpline.hxx>
59 #include <GEOMImpl_IEllipse.hxx>
60 #include <GEOMImpl_IArc.hxx>
61 #include <GEOMImpl_ISketcher.hxx>
62 #include <GEOMImpl_I3DSketcher.hxx>
63
64 #include "utilities.h"
65
66 #include <TDF_Tool.hxx>
67
68 #include <Standard_Failure.hxx>
69 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
70
71
72 /* ==================================
73  * ===========  PYTHON ==============
74  * ==================================*/
75
76 typedef struct {
77   PyObject_HEAD
78   int softspace;
79   std::string *out;
80   } PyStdOut;
81
82 static void
83 PyStdOut_dealloc(PyStdOut *self)
84 {
85   PyObject_Del(self);
86 }
87
88 static PyObject *
89 PyStdOut_write(PyStdOut *self, PyObject *args)
90 {
91   char *c;
92   int l;
93   if (!PyArg_ParseTuple(args, "t#:write",&c, &l))
94     return NULL;
95
96   //std::cerr << c ;
97   *(self->out)=*(self->out)+c;
98
99   Py_INCREF(Py_None);
100   return Py_None;
101 }
102
103 static PyMethodDef PyStdOut_methods[] = {
104   {"write",  (PyCFunction)PyStdOut_write,  METH_VARARGS,
105     PyDoc_STR("write(string) -> None")},
106   {NULL,    NULL}   /* sentinel */
107 };
108
109 static PyMemberDef PyStdOut_memberlist[] = {
110   {(char*)"softspace", T_INT,  offsetof(PyStdOut, softspace), 0,
111    (char*)"flag indicating that a space needs to be printed; used by print"},
112   {NULL} /* Sentinel */
113 };
114
115 static PyTypeObject PyStdOut_Type = {
116   /* The ob_type field must be initialized in the module init function
117    * to be portable to Windows without using C++. */
118   PyObject_HEAD_INIT(NULL)
119   0,                            /*ob_size*/
120   "PyOut",                      /*tp_name*/
121   sizeof(PyStdOut),             /*tp_basicsize*/
122   0,                            /*tp_itemsize*/
123   /* methods */
124   (destructor)PyStdOut_dealloc, /*tp_dealloc*/
125   0,                            /*tp_print*/
126   0,                            /*tp_getattr*/
127   0,                            /*tp_setattr*/
128   0,                            /*tp_compare*/
129   0,                            /*tp_repr*/
130   0,                            /*tp_as_number*/
131   0,                            /*tp_as_sequence*/
132   0,                            /*tp_as_mapping*/
133   0,                            /*tp_hash*/
134   0,                            /*tp_call*/
135   0,                            /*tp_str*/
136   PyObject_GenericGetAttr,      /*tp_getattro*/
137   /* softspace is writable:  we must supply tp_setattro */
138   PyObject_GenericSetAttr,      /* tp_setattro */
139   0,                            /*tp_as_buffer*/
140   Py_TPFLAGS_DEFAULT,           /*tp_flags*/
141   0,                            /*tp_doc*/
142   0,                            /*tp_traverse*/
143   0,                            /*tp_clear*/
144   0,                            /*tp_richcompare*/
145   0,                            /*tp_weaklistoffset*/
146   0,                            /*tp_iter*/
147   0,                            /*tp_iternext*/
148   PyStdOut_methods,             /*tp_methods*/
149   PyStdOut_memberlist,          /*tp_members*/
150   0,                            /*tp_getset*/
151   0,                            /*tp_base*/
152   0,                            /*tp_dict*/
153   0,                            /*tp_descr_get*/
154   0,                            /*tp_descr_set*/
155   0,                            /*tp_dictoffset*/
156   0,                            /*tp_init*/
157   0,                            /*tp_alloc*/
158   0,                            /*tp_new*/
159   0,                            /*tp_free*/
160   0,                            /*tp_is_gc*/
161 };
162
163 PyObject * newPyStdOut( std::string& out )
164 {
165   PyStdOut *self;
166   self = PyObject_New(PyStdOut, &PyStdOut_Type);
167   if (self == NULL)
168     return NULL;
169   self->softspace = 0;
170   self->out=&out;
171   return (PyObject*)self;
172 }
173
174
175 ////////////////////////END PYTHON///////////////////////////
176 //=============================================================================
177 /*!
178  *   constructor:
179  */
180 //=============================================================================
181 GEOMImpl_ICurvesOperations::GEOMImpl_ICurvesOperations (GEOM_Engine* theEngine, int theDocID)
182 : GEOM_IOperations(theEngine, theDocID)
183 {
184   MESSAGE("GEOMImpl_ICurvesOperations::GEOMImpl_ICurvesOperations");
185 }
186
187 //=============================================================================
188 /*!
189  *  destructor
190  */
191 //=============================================================================
192 GEOMImpl_ICurvesOperations::~GEOMImpl_ICurvesOperations()
193 {
194   MESSAGE("GEOMImpl_ICurvesOperations::~GEOMImpl_ICurvesOperations");
195 }
196
197
198 //=============================================================================
199 /*!
200  *  MakeCircleThreePnt
201  */
202 //=============================================================================
203 Handle(GEOM_Object) GEOMImpl_ICurvesOperations::MakeCircleThreePnt (Handle(GEOM_Object) thePnt1,
204                                                                     Handle(GEOM_Object) thePnt2,
205                                                                     Handle(GEOM_Object) thePnt3)
206 {
207   SetErrorCode(KO);
208
209   if (thePnt1.IsNull() || thePnt2.IsNull() || thePnt3.IsNull()) return NULL;
210
211   //Add a new Circle object
212   Handle(GEOM_Object) aCircle = GetEngine()->AddObject(GetDocID(), GEOM_CIRCLE);
213
214   //Add a new Circle function for creation a circle relatively to three points
215   Handle(GEOM_Function) aFunction =
216     aCircle->AddFunction(GEOMImpl_CircleDriver::GetID(), CIRCLE_THREE_PNT);
217   if (aFunction.IsNull()) return NULL;
218
219   //Check if the function is set correctly
220   if (aFunction->GetDriverGUID() != GEOMImpl_CircleDriver::GetID()) return NULL;
221
222   GEOMImpl_ICircle aCI (aFunction);
223
224   Handle(GEOM_Function) aRefPnt1 = thePnt1->GetLastFunction();
225   Handle(GEOM_Function) aRefPnt2 = thePnt2->GetLastFunction();
226   Handle(GEOM_Function) aRefPnt3 = thePnt3->GetLastFunction();
227
228   if (aRefPnt1.IsNull() || aRefPnt2.IsNull() || aRefPnt3.IsNull()) return NULL;
229
230   aCI.SetPoint1(aRefPnt1);
231   aCI.SetPoint2(aRefPnt2);
232   aCI.SetPoint3(aRefPnt3);
233
234   //Compute the Circle value
235   try {
236 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
237     OCC_CATCH_SIGNALS;
238 #endif
239     if (!GetSolver()->ComputeFunction(aFunction)) {
240       SetErrorCode("Circle driver failed");
241       return NULL;
242     }
243   }
244   catch (Standard_Failure) {
245     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
246     SetErrorCode(aFail->GetMessageString());
247     return NULL;
248   }
249
250   //Make a Python command
251   GEOM::TPythonDump(aFunction) << aCircle << " = geompy.MakeCircleThreePnt("
252     << thePnt1 << ", " << thePnt2 << ", " << thePnt3 << ")";
253
254   SetErrorCode(OK);
255   return aCircle;
256 }
257
258 //=============================================================================
259 /*!
260  *  MakeCircleCenter2Pnt
261  */
262 //=============================================================================
263 Handle(GEOM_Object) GEOMImpl_ICurvesOperations::MakeCircleCenter2Pnt (Handle(GEOM_Object) thePnt1,
264                                                                       Handle(GEOM_Object) thePnt2,
265                                                                       Handle(GEOM_Object) thePnt3)
266 {
267   SetErrorCode(KO);
268
269   if (thePnt1.IsNull() || thePnt2.IsNull() || thePnt3.IsNull()) return NULL;
270
271   //Add a new Circle object
272   Handle(GEOM_Object) aCircle = GetEngine()->AddObject(GetDocID(), GEOM_CIRCLE);
273
274   //Add a new Circle function for creation a circle relatively to center and 2 points
275   Handle(GEOM_Function) aFunction =
276     aCircle->AddFunction(GEOMImpl_CircleDriver::GetID(), CIRCLE_CENTER_TWO_PNT);
277   if (aFunction.IsNull()) return NULL;
278
279   //Check if the function is set correctly
280   if (aFunction->GetDriverGUID() != GEOMImpl_CircleDriver::GetID()) return NULL;
281
282   GEOMImpl_ICircle aCI (aFunction);
283
284   Handle(GEOM_Function) aRefPnt1 = thePnt1->GetLastFunction();
285   Handle(GEOM_Function) aRefPnt2 = thePnt2->GetLastFunction();
286   Handle(GEOM_Function) aRefPnt3 = thePnt3->GetLastFunction();
287
288   if (aRefPnt1.IsNull() || aRefPnt2.IsNull() || aRefPnt3.IsNull()) return NULL;
289
290   aCI.SetPoint1(aRefPnt1);
291   aCI.SetPoint2(aRefPnt2);
292   aCI.SetPoint3(aRefPnt3);
293
294   //Compute the Circle value
295   try {
296 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
297     OCC_CATCH_SIGNALS;
298 #endif
299     if (!GetSolver()->ComputeFunction(aFunction)) {
300       SetErrorCode("Circle driver failed");
301       return NULL;
302     }
303   }
304   catch (Standard_Failure) {
305     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
306     SetErrorCode(aFail->GetMessageString());
307     return NULL;
308   }
309
310   //Make a Python command
311   GEOM::TPythonDump(aFunction) << aCircle << " = geompy.MakeCircleCenter2Pnt("
312     << thePnt1 << ", " << thePnt2 << ", " << thePnt3 << ")";
313
314   SetErrorCode(OK);
315   return aCircle;
316 }
317
318 //=============================================================================
319 /*!
320  *  MakeCirclePntVecR
321  */
322 //=============================================================================
323 Handle(GEOM_Object) GEOMImpl_ICurvesOperations::MakeCirclePntVecR
324        (Handle(GEOM_Object) thePnt, Handle(GEOM_Object) theVec, double theR)
325 {
326   SetErrorCode(KO);
327
328   // Not set thePnt means origin of global CS,
329   // Not set theVec means Z axis of global CS
330   //if (thePnt.IsNull() || theVec.IsNull()) return NULL;
331
332   //Add a new Circle object
333   Handle(GEOM_Object) aCircle = GetEngine()->AddObject(GetDocID(), GEOM_CIRCLE);
334
335   //Add a new Circle function for creation a circle relatively to point and vector
336   Handle(GEOM_Function) aFunction =
337     aCircle->AddFunction(GEOMImpl_CircleDriver::GetID(), CIRCLE_PNT_VEC_R);
338   if (aFunction.IsNull()) return NULL;
339
340   //Check if the function is set correctly
341   if (aFunction->GetDriverGUID() != GEOMImpl_CircleDriver::GetID()) return NULL;
342
343   GEOMImpl_ICircle aCI (aFunction);
344
345   if (!thePnt.IsNull()) {
346     Handle(GEOM_Function) aRefPnt = thePnt->GetLastFunction();
347     if (aRefPnt.IsNull()) return NULL;
348     aCI.SetCenter(aRefPnt);
349   }
350
351   if (!theVec.IsNull()) {
352     Handle(GEOM_Function) aRefVec = theVec->GetLastFunction();
353     if (aRefVec.IsNull()) return NULL;
354     aCI.SetVector(aRefVec);
355   }
356
357   aCI.SetRadius(theR);
358
359   //Compute the Circle value
360   try {
361 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
362     OCC_CATCH_SIGNALS;
363 #endif
364     if (!GetSolver()->ComputeFunction(aFunction)) {
365       SetErrorCode("Circle driver failed");
366       return NULL;
367     }
368   }
369   catch (Standard_Failure) {
370     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
371     SetErrorCode(aFail->GetMessageString());
372     return NULL;
373   }
374
375   //Make a Python command
376   GEOM::TPythonDump(aFunction) << aCircle << " = geompy.MakeCircle("
377     << thePnt << ", " << theVec << ", " << theR << ")";
378
379   SetErrorCode(OK);
380   return aCircle;
381 }
382
383 //=============================================================================
384 /*!
385  *  MakeEllipse
386  */
387 //=============================================================================
388 Handle(GEOM_Object) GEOMImpl_ICurvesOperations::MakeEllipse
389                        (Handle(GEOM_Object) thePnt, Handle(GEOM_Object) theVec,
390                         double theRMajor, double theRMinor,
391                         Handle(GEOM_Object) theVecMaj)
392 {
393   SetErrorCode(KO);
394
395   // Not set thePnt means origin of global CS,
396   // Not set theVec means Z axis of global CS
397   // Not set theVecMaj means X axis of global CS
398   //if (thePnt.IsNull() || theVec.IsNull()) return NULL;
399
400   //Add a new Ellipse object
401   Handle(GEOM_Object) anEll = GetEngine()->AddObject(GetDocID(), GEOM_ELLIPSE);
402
403   //Add a new Ellipse function
404   Handle(GEOM_Function) aFunction =
405     anEll->AddFunction(GEOMImpl_EllipseDriver::GetID(), ELLIPSE_PNT_VEC_RR);
406   if (aFunction.IsNull()) return NULL;
407
408   //Check if the function is set correctly
409   if (aFunction->GetDriverGUID() != GEOMImpl_EllipseDriver::GetID()) return NULL;
410
411   GEOMImpl_IEllipse aCI (aFunction);
412
413   if (!thePnt.IsNull()) {
414     Handle(GEOM_Function) aRefPnt = thePnt->GetLastFunction();
415     if (aRefPnt.IsNull()) return NULL;
416     aCI.SetCenter(aRefPnt);
417   }
418
419   if (!theVec.IsNull()) {
420     Handle(GEOM_Function) aRefVec = theVec->GetLastFunction();
421     if (aRefVec.IsNull()) return NULL;
422     aCI.SetVector(aRefVec);
423   }
424
425   aCI.SetRMajor(theRMajor);
426   aCI.SetRMinor(theRMinor);
427
428   if (!theVecMaj.IsNull()) {
429     Handle(GEOM_Function) aRefVecMaj = theVecMaj->GetLastFunction();
430     if (aRefVecMaj.IsNull()) return NULL;
431     aCI.SetVectorMajor(aRefVecMaj);
432   }
433
434   //Compute the Ellipse value
435   try {
436 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
437     OCC_CATCH_SIGNALS;
438 #endif
439     if (!GetSolver()->ComputeFunction(aFunction)) {
440       SetErrorCode("Ellipse driver failed");
441       return NULL;
442     }
443   }
444   catch (Standard_Failure) {
445     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
446     SetErrorCode(aFail->GetMessageString());
447     return NULL;
448   }
449
450   //Make a Python command
451   if (!theVecMaj.IsNull()) {
452     GEOM::TPythonDump(aFunction) << anEll << " = geompy.MakeEllipse("
453                                  << thePnt << ", " << theVec << ", " << theRMajor << ", " << theRMinor
454                                  << ", " << theVecMaj << ")";
455   }
456   else {
457     GEOM::TPythonDump(aFunction) << anEll << " = geompy.MakeEllipse("
458                                  << thePnt << ", " << theVec << ", " << theRMajor << ", " << theRMinor << ")";
459   }
460
461   SetErrorCode(OK);
462   return anEll;
463 }
464
465 //=============================================================================
466 /*!
467  *  MakeArc
468  */
469 //=============================================================================
470 Handle(GEOM_Object) GEOMImpl_ICurvesOperations::MakeArc (Handle(GEOM_Object) thePnt1,
471                                                          Handle(GEOM_Object) thePnt2,
472                                                          Handle(GEOM_Object) thePnt3)
473 {
474   SetErrorCode(KO);
475
476   if (thePnt1.IsNull() || thePnt2.IsNull() || thePnt3.IsNull()) return NULL;
477
478   //Add a new Circle Arc object
479   Handle(GEOM_Object) anArc = GetEngine()->AddObject(GetDocID(), GEOM_CIRC_ARC);
480
481   //Add a new Circle Arc function
482   Handle(GEOM_Function) aFunction =
483       anArc->AddFunction(GEOMImpl_ArcDriver::GetID(), CIRC_ARC_THREE_PNT);  
484
485   if (aFunction.IsNull()) return NULL;
486   
487   //Check if the function is set correctly
488   if (aFunction->GetDriverGUID() != GEOMImpl_ArcDriver::GetID()) return NULL;
489   GEOMImpl_IArc aCI (aFunction);
490
491   Handle(GEOM_Function) aRefPnt1 = thePnt1->GetLastFunction();
492   Handle(GEOM_Function) aRefPnt2 = thePnt2->GetLastFunction();
493   Handle(GEOM_Function) aRefPnt3 = thePnt3->GetLastFunction();
494   
495
496   if (aRefPnt1.IsNull() || aRefPnt2.IsNull() || aRefPnt3.IsNull()) return NULL;
497
498   aCI.SetPoint1(aRefPnt1);
499   aCI.SetPoint2(aRefPnt2);
500   aCI.SetPoint3(aRefPnt3);
501   
502   //Compute the Arc value
503   try {
504 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
505     OCC_CATCH_SIGNALS;
506 #endif
507     if (!GetSolver()->ComputeFunction(aFunction)) {
508       SetErrorCode("Arc driver failed");
509       return NULL;
510     }
511   }
512   catch (Standard_Failure) {
513     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
514     SetErrorCode(aFail->GetMessageString());
515     return NULL;
516   }
517
518   //Make a Python command
519   GEOM::TPythonDump(aFunction) << anArc << " = geompy.MakeArc("
520     << thePnt1 << ", " << thePnt2 << ", " << thePnt3 << ")";
521
522   SetErrorCode(OK);
523   return anArc;
524 }
525
526 //=============================================================================
527 /*!
528  *  MakeArcCenter
529  */
530 //=============================================================================
531 Handle(GEOM_Object) GEOMImpl_ICurvesOperations::MakeArcCenter (Handle(GEOM_Object) thePnt1,
532                                                                Handle(GEOM_Object) thePnt2,
533                                                                Handle(GEOM_Object) thePnt3,
534                                                                bool                theSense)
535 {
536   SetErrorCode(KO);
537   if (thePnt1.IsNull() || thePnt2.IsNull() || thePnt3.IsNull()) return NULL;
538
539   //Add a new Circle Arc object
540   Handle(GEOM_Object) anArc = GetEngine()->AddObject(GetDocID(), GEOM_CIRC_ARC);
541
542   //Add a new Circle Arc function
543   Handle(GEOM_Function) aFunction =
544       anArc->AddFunction(GEOMImpl_ArcDriver::GetID(), CIRC_ARC_CENTER);
545   if (aFunction.IsNull()) return NULL;
546
547   //Check if the function is set correctly
548   if (aFunction->GetDriverGUID() != GEOMImpl_ArcDriver::GetID()) return NULL;
549
550   GEOMImpl_IArc aCI (aFunction);
551
552   Handle(GEOM_Function) aRefPnt1 = thePnt1->GetLastFunction();
553   Handle(GEOM_Function) aRefPnt2 = thePnt2->GetLastFunction();
554   Handle(GEOM_Function) aRefPnt3 = thePnt3->GetLastFunction();
555
556   if (aRefPnt1.IsNull() || aRefPnt2.IsNull() || aRefPnt3.IsNull()) return NULL;
557
558   aCI.SetPoint1(aRefPnt1);
559   aCI.SetPoint2(aRefPnt2);
560   aCI.SetPoint3(aRefPnt3);
561   aCI.SetSense(theSense);
562
563   //Compute the Arc value
564   try {
565 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
566     OCC_CATCH_SIGNALS;
567 #endif
568     if (!GetSolver()->ComputeFunction(aFunction)) {
569   SetErrorCode("Arc driver failed");
570   return NULL;
571     }
572   }
573   catch (Standard_Failure) {
574     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
575     SetErrorCode(aFail->GetMessageString());
576     return NULL;
577   }
578   //Make a Python command
579   GEOM::TPythonDump(aFunction) << anArc << " = geompy.MakeArcCenter("
580       << thePnt1 << ", " << thePnt2 << ", " << thePnt3 << "," << theSense << ")";
581
582   SetErrorCode(OK);
583   return anArc;
584 }
585
586 //=============================================================================
587 /*!
588  *  MakeArcOfEllipse
589  */
590 //=============================================================================
591 Handle(GEOM_Object) GEOMImpl_ICurvesOperations::MakeArcOfEllipse (Handle(GEOM_Object) thePnt1,
592                                                                   Handle(GEOM_Object) thePnt2,
593                                                                   Handle(GEOM_Object) thePnt3)
594 {
595   SetErrorCode(KO);
596
597   if (thePnt1.IsNull() || thePnt2.IsNull() || thePnt3.IsNull()) return NULL;
598
599   //Add a new Circle Arc object
600   Handle(GEOM_Object) anArc = GetEngine()->AddObject(GetDocID(), GEOM_ELLIPSE_ARC);
601
602   //Add a new Circle Arc function
603   Handle(GEOM_Function) aFunction =
604       anArc->AddFunction(GEOMImpl_ArcDriver::GetID(), ELLIPSE_ARC_CENTER_TWO_PNT);
605
606   if (aFunction.IsNull()) return NULL;
607   
608   //Check if the function is set correctly
609   if (aFunction->GetDriverGUID() != GEOMImpl_ArcDriver::GetID()) return NULL;
610   GEOMImpl_IArc aCI (aFunction);
611
612   Handle(GEOM_Function) aRefPnt1 = thePnt1->GetLastFunction();
613   Handle(GEOM_Function) aRefPnt2 = thePnt2->GetLastFunction();
614   Handle(GEOM_Function) aRefPnt3 = thePnt3->GetLastFunction();
615   
616
617   if (aRefPnt1.IsNull() || aRefPnt2.IsNull() || aRefPnt3.IsNull()) return NULL;
618
619   aCI.SetPoint1(aRefPnt1);
620   aCI.SetPoint2(aRefPnt2);
621   aCI.SetPoint3(aRefPnt3);
622   
623   //Compute the Arc value
624   try {
625 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
626     OCC_CATCH_SIGNALS;
627 #endif
628     if (!GetSolver()->ComputeFunction(aFunction)) {
629       SetErrorCode("Arc driver failed");
630       return NULL;
631     }
632   }
633   catch (Standard_Failure) {
634     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
635     SetErrorCode(aFail->GetMessageString());
636     return NULL;
637   }
638
639   //Make a Python command
640   GEOM::TPythonDump(aFunction) << anArc << " = geompy.MakeArcOfEllipse("
641     << thePnt1 << ", " << thePnt2 << ", " << thePnt3 << ")";
642
643   SetErrorCode(OK);
644   return anArc;
645 }
646
647 //=============================================================================
648 /*!
649  *  MakePolyline
650  */
651 //=============================================================================
652 Handle(GEOM_Object) GEOMImpl_ICurvesOperations::MakePolyline (std::list<Handle(GEOM_Object)> thePoints,
653                                                               bool theIsClosed)
654 {
655   SetErrorCode(KO);
656
657   //Add a new Polyline object
658   Handle(GEOM_Object) aPolyline = GetEngine()->AddObject(GetDocID(), GEOM_POLYLINE);
659
660   //Add a new Polyline function for creation a polyline relatively to points set
661   Handle(GEOM_Function) aFunction =
662     aPolyline->AddFunction(GEOMImpl_PolylineDriver::GetID(), POLYLINE_POINTS);
663   if (aFunction.IsNull()) return NULL;
664
665   //Check if the function is set correctly
666   if (aFunction->GetDriverGUID() != GEOMImpl_PolylineDriver::GetID()) return NULL;
667
668   GEOMImpl_IPolyline aCI (aFunction);
669
670   int aLen = thePoints.size();
671   aCI.SetLength(aLen);
672   aCI.SetConstructorType(POINT_CONSTRUCTOR);
673
674   int ind = 1;
675   std::list<Handle(GEOM_Object)>::iterator it = thePoints.begin();
676   for (; it != thePoints.end(); it++, ind++) {
677     Handle(GEOM_Function) aRefPnt = (*it)->GetLastFunction();
678     if (aRefPnt.IsNull()) {
679       SetErrorCode("NULL point for Polyline");
680       return NULL;
681     }
682     aCI.SetPoint(ind, aRefPnt);
683   }
684
685   aCI.SetIsClosed(theIsClosed);
686
687   //Compute the Polyline value
688   try {
689 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
690     OCC_CATCH_SIGNALS;
691 #endif
692     if (!GetSolver()->ComputeFunction(aFunction)) {
693       SetErrorCode("Polyline driver failed");
694       return NULL;
695     }
696   }
697   catch (Standard_Failure) {
698     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
699     SetErrorCode(aFail->GetMessageString());
700     return NULL;
701   }
702
703   //Make a Python command
704   GEOM::TPythonDump pd (aFunction);
705   pd << aPolyline << " = geompy.MakePolyline([";
706
707   it = thePoints.begin();
708   pd << (*it++);
709   while (it != thePoints.end()) {
710     pd << ", " << (*it++);
711   }
712   pd << "], " << theIsClosed << ")";
713
714   SetErrorCode(OK);
715   return aPolyline;
716 }
717
718 //=============================================================================
719 /*!
720  *  MakeSplineBezier
721  */
722 //=============================================================================
723 Handle(GEOM_Object) GEOMImpl_ICurvesOperations::MakeSplineBezier
724                                           (std::list<Handle(GEOM_Object)> thePoints,
725                                            bool theIsClosed)
726 {
727   SetErrorCode(KO);
728
729   //Add a new Spline object
730   Handle(GEOM_Object) aSpline = GetEngine()->AddObject(GetDocID(), GEOM_SPLINE);
731
732   //Add a new Spline function for creation a bezier curve relatively to points set
733   Handle(GEOM_Function) aFunction =
734     aSpline->AddFunction(GEOMImpl_SplineDriver::GetID(), SPLINE_BEZIER);
735   if (aFunction.IsNull()) return NULL;
736
737   //Check if the function is set correctly
738   if (aFunction->GetDriverGUID() != GEOMImpl_SplineDriver::GetID()) return NULL;
739
740   GEOMImpl_ISpline aCI (aFunction);
741
742   int aLen = thePoints.size();
743   aCI.SetLength(aLen);
744   aCI.SetConstructorType(POINT_CONSTRUCTOR);
745
746   int ind = 1;
747   std::list<Handle(GEOM_Object)>::iterator it = thePoints.begin();
748   for (; it != thePoints.end(); it++, ind++) {
749     Handle(GEOM_Function) aRefPnt = (*it)->GetLastFunction();
750
751     if (aRefPnt.IsNull()) return NULL;
752
753     aCI.SetPoint(ind, aRefPnt);
754   }
755
756   aCI.SetIsClosed(theIsClosed);
757
758   //Compute the Spline value
759   try {
760 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
761     OCC_CATCH_SIGNALS;
762 #endif
763     if (!GetSolver()->ComputeFunction(aFunction)) {
764       SetErrorCode("Spline driver failed");
765       return NULL;
766     }
767   }
768   catch (Standard_Failure) {
769     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
770     SetErrorCode(aFail->GetMessageString());
771     return NULL;
772   }
773
774   //Make a Python command
775   GEOM::TPythonDump pd (aFunction);
776   pd << aSpline << " = geompy.MakeBezier([";
777
778   it = thePoints.begin();
779   pd << (*it++);
780   while (it != thePoints.end()) {
781     pd << ", " << (*it++);
782   }
783   pd << "], " << theIsClosed << ")";
784
785   SetErrorCode(OK);
786   return aSpline;
787 }
788
789 //=============================================================================
790 /*!
791  *  MakeSplineInterpolation
792  */
793 //=============================================================================
794 Handle(GEOM_Object) GEOMImpl_ICurvesOperations::MakeSplineInterpolation
795                                           (std::list<Handle(GEOM_Object)> thePoints,
796                                            bool theIsClosed,
797                                            bool theDoReordering)
798 {
799   SetErrorCode(KO);
800
801   //Add a new Spline object
802   Handle(GEOM_Object) aSpline = GetEngine()->AddObject(GetDocID(), GEOM_SPLINE);
803
804   //Add a new Spline function for creation a bezier curve relatively to points set
805   Handle(GEOM_Function) aFunction =
806     aSpline->AddFunction(GEOMImpl_SplineDriver::GetID(), SPLINE_INTERPOLATION);
807   if (aFunction.IsNull()) return NULL;
808
809   //Check if the function is set correctly
810   if (aFunction->GetDriverGUID() != GEOMImpl_SplineDriver::GetID()) return NULL;
811
812   GEOMImpl_ISpline aCI (aFunction);
813
814   int aLen = thePoints.size();
815   aCI.SetConstructorType(POINT_CONSTRUCTOR);
816   aCI.SetLength(aLen);
817
818   int ind = 1;
819   std::list<Handle(GEOM_Object)>::iterator it = thePoints.begin();
820   for (; it != thePoints.end(); it++, ind++) {
821     Handle(GEOM_Function) aRefPnt = (*it)->GetLastFunction();
822
823     if (aRefPnt.IsNull()) return NULL;
824
825     aCI.SetPoint(ind, aRefPnt);
826   }
827
828   aCI.SetIsClosed(theIsClosed);
829   aCI.SetDoReordering(theDoReordering);
830
831   //Compute the Spline value
832   try {
833 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
834     OCC_CATCH_SIGNALS;
835 #endif
836     if (!GetSolver()->ComputeFunction(aFunction)) {
837       SetErrorCode("Spline driver failed");
838       return NULL;
839     }
840   }
841   catch (Standard_Failure) {
842     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
843     SetErrorCode(aFail->GetMessageString());
844     return NULL;
845   }
846
847   //Make a Python command
848   GEOM::TPythonDump pd (aFunction);
849   pd << aSpline << " = geompy.MakeInterpol([";
850
851   it = thePoints.begin();
852   pd << (*it++);
853   while (it != thePoints.end()) {
854     pd << ", " << (*it++);
855   }
856   pd << "], " << theIsClosed << ", " << theDoReordering << ")";
857
858   SetErrorCode(OK);
859   return aSpline;
860 }
861
862 //=============================================================================
863 /*!
864  *  MakeCurveParametric
865  */
866 //=============================================================================
867 Handle(GEOM_Object) GEOMImpl_ICurvesOperations::MakeCurveParametric(const char* thexExpr, const char* theyExpr, const char* thezExpr, 
868                                                                     double theParamMin, double theParamMax, double theParamStep, 
869                                                                     CurveType theCurveType) {
870   TCollection_AsciiString aPyScript;
871   aPyScript +="from math import *                                          \n";
872   aPyScript +="def X(t):                                                   \n";
873   aPyScript +="    return "; 
874   aPyScript += thexExpr;
875   aPyScript += "\n";                                                             
876   aPyScript +="def Y(t):                                                   \n";
877   aPyScript +="    return ";
878   aPyScript += theyExpr;
879   aPyScript += "\n";
880   
881   aPyScript +="def Z(t):                                                   \n";
882   aPyScript +="    return ";
883   aPyScript += thezExpr;
884   aPyScript += "\n";
885   
886   aPyScript +="def coordCalculator(tmin, tmax, tstep):                      \n";
887   aPyScript +="   coords = []                                              \n";
888   aPyScript +="   while tmin <= tmax :                                     \n";
889   aPyScript +="      coords.append([X(tmin), Y(tmin), Z(tmin)])            \n";
890   aPyScript +="      tmin = tmin + tstep                                   \n";
891   aPyScript +="   return coords                                            \n";
892   
893   SetErrorCode(KO);
894
895   if(theParamMin >= theParamMax) {
896     SetErrorCode("The minimum value of the parameter must be less than maximum value !!!");
897     return NULL;
898   }
899
900   if(theParamStep <= 0.0 ) {
901     SetErrorCode("Value of the step must be positive !!!");
902     return NULL;
903   }
904   
905   /* Initialize the Python interpreter */
906   if (! Py_IsInitialized()) {
907     SetErrorCode("Python interpreter is not initialized !!! ");
908     return NULL;
909   } 
910
911   PyGILState_STATE gstate;
912   gstate = PyGILState_Ensure();
913   
914   PyObject* main_mod = PyImport_AddModule("__main__");
915   PyObject* main_dict = PyModule_GetDict(main_mod);
916
917   PyObject* obj = PyRun_String(aPyScript.ToCString(), Py_file_input, main_dict, NULL);
918
919   if (obj == NULL) {
920     SetErrorCode("Error during executing of python script !!!");
921     PyErr_Print();
922     PyGILState_Release(gstate);
923     return NULL;
924   } else {
925     Py_DECREF(obj);
926   }
927
928   PyObject * func = NULL;
929   func = PyObject_GetAttrString(main_mod, "coordCalculator");
930   
931   if (func == NULL){
932     SetErrorCode("Can't get function from python module !!!");
933     PyGILState_Release(gstate);
934     return NULL;
935   }
936   
937   PyObject* coords = PyObject_CallFunction(func,(char*)"(d, d, d)", theParamMin, theParamMax, theParamStep );
938   PyObject* new_stderr = NULL;
939
940   if (coords == NULL){
941     fflush(stderr);
942     std::string err_description="";
943     new_stderr = newPyStdOut(err_description);
944     PySys_SetObject((char*)"stderr", new_stderr);
945     PyErr_Print();
946     PySys_SetObject((char*)"stderr", PySys_GetObject((char*)"__stderr__"));
947     Py_DECREF(new_stderr);
948     MESSAGE("Can't evaluate coordCalculator()" << " error is " << err_description);
949     SetErrorCode("Can't evaluate the expressions, please check them !!!");
950     PyGILState_Release(gstate);
951     return NULL;
952   }
953
954   Handle(TColStd_HArray1OfReal) aCoordsArray = new TColStd_HArray1OfReal (1, PyList_Size( coords ) * 3);
955
956   if(PyList_Size( coords ) <= 0) {
957     SetErrorCode("Empty list of the points, please check input parameters !!!");
958     return NULL;
959   }    
960
961   int k=1;
962   for ( Py_ssize_t i = 0; i< PyList_Size( coords ); ++i ) {
963     PyObject* coord = PyList_GetItem( coords, i );
964     if (coord != NULL) {
965       for ( Py_ssize_t j = 0; j < PyList_Size(coord); ++j) {
966         PyObject* item = PyList_GetItem(coord, j);
967         aCoordsArray->SetValue(k, PyFloat_AsDouble(item));
968         k++;
969       }
970     }
971   }
972
973   Py_DECREF(coords);
974
975   
976   
977   PyGILState_Release(gstate);
978
979   Handle(GEOM_Object) aCurve; 
980   Handle(GEOM_Function) aFunction;
981   TCollection_AsciiString aCurveType;
982   
983   switch(theCurveType) {
984   case Polyline: {
985     //Add a new Polyline object
986     aCurve = GetEngine()->AddObject(GetDocID(), GEOM_POLYLINE);
987     
988     //Add a new Polyline function for creation a polyline relatively to points set
989     aFunction = aCurve->AddFunction(GEOMImpl_PolylineDriver::GetID(), POLYLINE_POINTS);
990     if (aFunction.IsNull()) return NULL;
991     
992     //Check if the function is set correctly
993     if (aFunction->GetDriverGUID() != GEOMImpl_PolylineDriver::GetID()) return NULL;
994
995     GEOMImpl_IPolyline aCI (aFunction);
996
997     aCI.SetLength(PyList_Size( coords ));
998     aCI.SetConstructorType(COORD_CONSTRUCTOR);
999     aCI.SetIsClosed(false);
1000     aCI.SetCoordinates(aCoordsArray);
1001     aCurveType = "geompy.GEOM.Polyline";
1002     break;
1003   }
1004   case Bezier: {
1005     //Add a new Spline object
1006     aCurve = GetEngine()->AddObject(GetDocID(), GEOM_SPLINE);
1007     //Add a new Spline function for creation a bezier curve relatively to points set
1008     aFunction =
1009       aCurve->AddFunction(GEOMImpl_SplineDriver::GetID(), SPLINE_BEZIER);
1010     if (aFunction.IsNull()) return NULL;
1011     
1012     //Check if the function is set correctly
1013     if (aFunction->GetDriverGUID() != GEOMImpl_SplineDriver::GetID()) return NULL;
1014     
1015     GEOMImpl_ISpline aCI (aFunction);
1016
1017     aCI.SetLength(PyList_Size( coords ));
1018     aCI.SetConstructorType(COORD_CONSTRUCTOR);
1019     aCI.SetIsClosed(false);
1020     aCI.SetCoordinates(aCoordsArray);
1021     aCurveType = "geompy.GEOM.Bezier";
1022     break;
1023   }
1024   case Interpolation: {
1025     //Add a new Spline object
1026     aCurve = GetEngine()->AddObject(GetDocID(), GEOM_SPLINE);
1027
1028     //Add a new Spline function for creation a bezier curve relatively to points set
1029     aFunction = aCurve->AddFunction(GEOMImpl_SplineDriver::GetID(), SPLINE_INTERPOLATION);
1030     if (aFunction.IsNull()) return NULL;
1031     
1032     //Check if the function is set correctly
1033     if (aFunction->GetDriverGUID() != GEOMImpl_SplineDriver::GetID()) return NULL;
1034
1035     GEOMImpl_ISpline aCI (aFunction);
1036     aCI.SetConstructorType(COORD_CONSTRUCTOR);
1037     aCI.SetLength(PyList_Size( coords ));
1038     aCI.SetIsClosed(false);
1039     aCI.SetDoReordering(false);
1040     aCI.SetCoordinates(aCoordsArray);
1041     aCurveType = "geompy.GEOM.Interpolation";
1042     break;
1043   }
1044   }
1045
1046   //Compute the Curve value
1047   try {
1048 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1049     OCC_CATCH_SIGNALS;
1050 #endif
1051     if (!GetSolver()->ComputeFunction(aFunction)) {
1052       SetErrorCode("Curve driver failed !!!");
1053       return NULL;
1054     }
1055   }
1056   catch (Standard_Failure) {
1057     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1058     SetErrorCode(aFail->GetMessageString());
1059     return NULL;
1060   }
1061   
1062   //Make a Python command
1063   GEOM::TPythonDump pd (aFunction);
1064   pd << aCurve << " = geompy.MakeCurveParametric(";
1065   pd << "\"" << thexExpr << "\", ";
1066   pd << "\"" << theyExpr << "\", ";
1067   pd << "\"" << thezExpr << "\", ";
1068   
1069   pd << theParamMin <<", ";
1070   pd << theParamMax <<", ";
1071   pd << theParamStep <<", ";
1072   pd << aCurveType.ToCString() <<")";
1073   
1074   SetErrorCode(OK);
1075   return aCurve;
1076 }
1077
1078 //=============================================================================
1079 /*!
1080  *  MakeSketcher
1081  */
1082 //=============================================================================
1083 Handle(GEOM_Object) GEOMImpl_ICurvesOperations::MakeSketcher (const char* theCommand,
1084                                                               std::list<double> theWorkingPlane)
1085 {
1086   SetErrorCode(KO);
1087
1088   if (!theCommand || strcmp(theCommand, "") == 0) return NULL;
1089
1090   //Add a new Sketcher object
1091   Handle(GEOM_Object) aSketcher = GetEngine()->AddObject(GetDocID(), GEOM_SKETCHER);
1092
1093   //Add a new Sketcher function
1094   Handle(GEOM_Function) aFunction =
1095     aSketcher->AddFunction(GEOMImpl_SketcherDriver::GetID(), SKETCHER_NINE_DOUBLS);
1096   if (aFunction.IsNull()) return NULL;
1097
1098   //Check if the function is set correctly
1099   if (aFunction->GetDriverGUID() != GEOMImpl_SketcherDriver::GetID()) return NULL;
1100
1101   GEOMImpl_ISketcher aCI (aFunction);
1102
1103   TCollection_AsciiString aCommand((char*) theCommand);
1104   aCI.SetCommand(aCommand);
1105
1106   int ind = 1;
1107   std::list<double>::iterator it = theWorkingPlane.begin();
1108   for (; it != theWorkingPlane.end(); it++, ind++)
1109     aCI.SetWorkingPlane(ind, *it);
1110
1111   //Compute the Sketcher value
1112   try {
1113 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1114     OCC_CATCH_SIGNALS;
1115 #endif
1116     if (!GetSolver()->ComputeFunction(aFunction)) {
1117       SetErrorCode("Sketcher driver failed");
1118       return NULL;
1119     }
1120   }
1121   catch (Standard_Failure) {
1122     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1123     SetErrorCode(aFail->GetMessageString());
1124     return NULL;
1125   }
1126
1127   //Make a Python command
1128   GEOM::TPythonDump pd (aFunction);
1129   pd << aSketcher << " = geompy.MakeSketcher(\"" << aCommand.ToCString() << "\", [";
1130
1131   it = theWorkingPlane.begin();
1132   pd << (*it++);
1133   while (it != theWorkingPlane.end()) {
1134     pd << ", " << (*it++);
1135   }
1136   pd << "])";
1137
1138   SetErrorCode(OK);
1139   return aSketcher;
1140 }
1141
1142 //=============================================================================
1143 /*!
1144  *  Make3DSketcher
1145  */
1146 //=============================================================================
1147 Handle(GEOM_Object) GEOMImpl_ICurvesOperations::Make3DSketcher (std::list<double> theCoordinates)
1148 {
1149   SetErrorCode(KO);
1150
1151   //Add a new Sketcher object
1152   Handle(GEOM_Object) a3DSketcher = GetEngine()->AddObject(GetDocID(), GEOM_3DSKETCHER);
1153
1154   //Add a new Sketcher function
1155   Handle(GEOM_Function) aFunction =
1156     a3DSketcher->AddFunction(GEOMImpl_3DSketcherDriver::GetID(), GEOM_3DSKETCHER);
1157   if (aFunction.IsNull()) return NULL;
1158
1159   //Check if the function is set correctly
1160   if (aFunction->GetDriverGUID() != GEOMImpl_3DSketcherDriver::GetID()) return NULL;
1161
1162   GEOMImpl_I3DSketcher aCI (aFunction);
1163
1164   int nbOfCoords = 0;
1165   std::list<double>::iterator it = theCoordinates.begin();
1166   for (; it != theCoordinates.end(); it++)
1167     nbOfCoords++;
1168
1169   Handle(TColStd_HArray1OfReal) aCoordsArray = new TColStd_HArray1OfReal (1, nbOfCoords);
1170
1171   it = theCoordinates.begin();
1172   int ind = 1;
1173   for (; it != theCoordinates.end(); it++, ind++)
1174     aCoordsArray->SetValue(ind, *it);
1175
1176   aCI.SetCoordinates(aCoordsArray);
1177     
1178   //Compute the Sketcher value
1179   try {
1180 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1181     OCC_CATCH_SIGNALS;
1182 #endif
1183     if (!GetSolver()->ComputeFunction(aFunction)) {
1184       SetErrorCode("3D Sketcher driver failed");
1185       return NULL;
1186     }
1187   }
1188   catch (Standard_Failure) {
1189     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1190     SetErrorCode(aFail->GetMessageString());
1191     return NULL;
1192   }
1193
1194   //Make a Python command
1195   GEOM::TPythonDump pd (aFunction);
1196   pd << a3DSketcher << " = geompy.Make3DSketcher([";
1197
1198   it = theCoordinates.begin();
1199   pd << (*it++);
1200   while (it != theCoordinates.end()) {
1201     pd << ", " << (*it++);
1202   }
1203   pd << "])";
1204
1205   SetErrorCode(OK);
1206   return a3DSketcher;
1207 }
1208
1209 //=============================================================================
1210 /*!
1211  *  MakeSketcherOnPlane
1212  */
1213 //=============================================================================
1214 Handle(GEOM_Object) GEOMImpl_ICurvesOperations::MakeSketcherOnPlane
1215                                (const char* theCommand,
1216                                 Handle(GEOM_Object)            theWorkingPlane)
1217 {
1218   SetErrorCode(KO);
1219
1220   if (!theCommand || strcmp(theCommand, "") == 0) return NULL;
1221
1222   //Add a new Sketcher object
1223   Handle(GEOM_Object) aSketcher = GetEngine()->AddObject(GetDocID(), GEOM_SKETCHER);
1224
1225   //Add a new Sketcher function
1226   Handle(GEOM_Function) aFunction =
1227     aSketcher->AddFunction(GEOMImpl_SketcherDriver::GetID(), SKETCHER_PLANE);
1228   if (aFunction.IsNull()) return NULL;
1229
1230   //Check if the function is set correctly
1231   if (aFunction->GetDriverGUID() != GEOMImpl_SketcherDriver::GetID()) return NULL;
1232
1233   GEOMImpl_ISketcher aCI (aFunction);
1234
1235   TCollection_AsciiString aCommand((char*) theCommand);
1236   aCI.SetCommand(aCommand);
1237
1238   Handle(GEOM_Function) aRefPlane = theWorkingPlane->GetLastFunction();
1239   if (aRefPlane.IsNull()) return NULL;
1240   aCI.SetWorkingPlane( aRefPlane );
1241
1242   //Compute the Sketcher value
1243   try {
1244 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1245     OCC_CATCH_SIGNALS;
1246 #endif
1247     if (!GetSolver()->ComputeFunction(aFunction)) {
1248       SetErrorCode("Sketcher driver failed");
1249       return NULL;
1250     }
1251   }
1252   catch (Standard_Failure) {
1253     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1254     SetErrorCode(aFail->GetMessageString());
1255     return NULL;
1256   }
1257
1258   //Make a Python command
1259   GEOM::TPythonDump (aFunction) << aSketcher << " = geompy.MakeSketcherOnPlane(\""
1260     << aCommand.ToCString() << "\", " << theWorkingPlane << " )";
1261
1262   SetErrorCode(OK);
1263   return aSketcher;
1264 }
1265