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