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