Salome HOME
0021031: EDF 1646 GEOM: Modify Location leads to Position driver failed
[modules/geom.git] / src / GEOMImpl / GEOMImpl_IHealingOperations.cxx
1 //  Copyright (C) 2007-2010  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 #pragma warning( disable:4786 )
24 #endif
25
26 #include <Standard_Version.hxx>
27 #include <Standard_Stream.hxx>
28
29 #include <GEOMImpl_IHealingOperations.hxx>
30
31 #include <GEOM_PythonDump.hxx>
32
33 #include <GEOMImpl_HealingDriver.hxx>
34 #include <GEOMImpl_Types.hxx>
35 #include <GEOMImpl_IHealing.hxx>
36 #include <GEOMImpl_CopyDriver.hxx>
37
38 #include <ShHealOper_ShapeProcess.hxx>
39
40 #include "utilities.h"
41 #include <OpUtil.hxx>
42 #include <Utils_ExceptHandlers.hxx>
43
44 #include <ShapeAnalysis_FreeBounds.hxx>
45
46 #include <TopoDS_Compound.hxx>
47 #include <TopExp_Explorer.hxx>
48
49 #include <TColStd_HArray1OfExtendedString.hxx>
50 #include <TColStd_HSequenceOfTransient.hxx>
51 #include <TCollection_AsciiString.hxx>
52
53 #include <TDF_Tool.hxx>
54
55 #include <Standard_Failure.hxx>
56 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
57
58 #ifdef OCC_VERSION_SERVICEPACK
59 #define OCC_VERSION_LARGE (OCC_VERSION_MAJOR << 24 | OCC_VERSION_MINOR << 16 | OCC_VERSION_MAINTENANCE << 8 | OCC_VERSION_SERVICEPACK)
60 #else
61 #define OCC_VERSION_LARGE (OCC_VERSION_MAJOR << 24 | OCC_VERSION_MINOR << 16 | OCC_VERSION_MAINTENANCE << 8)
62 #endif
63
64
65 //=============================================================================
66 /*!
67  *   constructor:
68  */
69 //=============================================================================
70
71 GEOMImpl_IHealingOperations::GEOMImpl_IHealingOperations (GEOM_Engine* theEngine, int theDocID)
72 : GEOM_IOperations(theEngine, theDocID)
73 {
74   MESSAGE("GEOMImpl_IHealingOperations::GEOMImpl_IHealingOperations");
75 }
76
77 //=============================================================================
78 /*!
79  *  destructor
80  */
81 //=============================================================================
82
83 GEOMImpl_IHealingOperations::~GEOMImpl_IHealingOperations()
84 {
85   MESSAGE("GEOMImpl_IHealingOperations::~GEOMImpl_IHealingOperations");
86 }
87
88
89 //=============================================================================
90 /*!
91  *  ShapeProcess
92  */
93 //=============================================================================
94 Handle(GEOM_Object) GEOMImpl_IHealingOperations::ShapeProcess (Handle(GEOM_Object) theObject,
95                                   const Handle(TColStd_HArray1OfExtendedString)& theOperators,
96                                   const Handle(TColStd_HArray1OfExtendedString)& theParams,
97                                   const Handle(TColStd_HArray1OfExtendedString)& theValues)
98 {
99   // set error code, check parameters
100   SetErrorCode(KO);
101
102   if (theObject.IsNull())
103     return NULL;
104
105   if (theOperators.IsNull() || theOperators->Length() <= 0) {
106     SetErrorCode("No operators requested");
107     return NULL;
108   }
109
110   Standard_Integer nbParams = 0, nbValues = 0;
111   if (!theParams.IsNull()) {
112     nbParams = theParams->Length();
113   }
114   if (!theValues.IsNull()) {
115     nbValues = theValues->Length();
116   }
117
118   if (nbParams != nbValues) {
119     SetErrorCode("Number of parameter values must be equal to the number of parameters");
120     return NULL;
121   }
122
123   Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
124   if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
125
126   // Add a new object
127   Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
128
129   //Add the function
130   aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), SHAPE_PROCESS);
131
132   if (aFunction.IsNull()) return NULL;
133
134   //Check if the function is set correctly
135   if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
136
137   // prepare "data container" class IHealing
138   GEOMImpl_IHealing HI(aFunction);
139   HI.SetOriginal(aLastFunction);
140   HI.SetOperators( theOperators );
141   if (nbParams > 0) {
142     HI.SetParameters( theParams );
143     HI.SetValues( theValues );
144   }
145
146   //Compute the translation
147   try {
148 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
149     OCC_CATCH_SIGNALS;
150 #endif
151     if (!GetSolver()->ComputeFunction(aFunction))
152     {
153       SetErrorCode("Shape Healing algorithm failed");
154       return NULL;
155     }
156   }
157   catch (Standard_Failure)
158   {
159     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
160     SetErrorCode(aFail->GetMessageString());
161     return NULL;
162   }
163
164   //Make a Python command
165   GEOM::TPythonDump pd (aFunction);
166   pd << aNewObject << " = geompy.ProcessShape(" << theObject << ", [";
167
168   // list of operators
169   int i = theOperators->Lower(), nb = theOperators->Upper();
170   for ( ; i <= nb; i++) {
171     pd << "\"" << TCollection_AsciiString(theOperators->Value( i )).ToCString()
172       << (( i < nb ) ? "\", " : "\"");
173   }
174   pd << "], [";
175   // list of parameters
176   i = theParams->Lower(); nb = theParams->Upper();
177   for ( ; i <= nb; i++) {
178     pd << "\"" << TCollection_AsciiString(theParams->Value( i )).ToCString()
179       << (( i < nb ) ? "\", " : "\"");
180   }
181   pd << "], [";
182   // list of values
183   i = theValues->Lower(); nb = theValues->Upper();
184   for ( ; i <= nb; i++) {
185     pd << "\"" << TCollection_AsciiString(theValues->Value( i )).ToCString()
186       << (( i < nb ) ? "\", " : "\"");
187   }
188   pd << "])";
189
190   SetErrorCode(OK);
191   return aNewObject;
192 }
193
194 //=============================================================================
195 /*!
196  *  ShapeProcess
197  */
198 //=============================================================================
199 void GEOMImpl_IHealingOperations::GetShapeProcessParameters (std::list<std::string>& theOperations,
200                                                              std::list<std::string>& theParams,
201                                                              std::list<std::string>& theValues)
202 {
203   ShHealOper_ShapeProcess aHealer;
204   TColStd_SequenceOfAsciiString anOperators;
205   int nbOperatorErrors( 0 );
206   if ( aHealer.GetOperators( anOperators ) )
207   {
208     for ( Standard_Integer i = 1; i <= anOperators.Length(); i++ )
209     {
210       std::string anOperation = anOperators.Value( i ).ToCString();
211       if ( GetOperatorParameters( anOperation, theParams, theValues ) )
212         theOperations.push_back( anOperation );
213       else
214         nbOperatorErrors++;
215     }
216   }
217   else
218   {
219     SetErrorCode("ERROR retrieving operators (GEOMImpl_IHealingOperations)");
220   }
221
222   if ( nbOperatorErrors ) {
223     TCollection_AsciiString aMsg ("ERRORS retrieving ShapeProcess parameters (GEOMImpl_IHealingOperations): nbOperatorErrors = ");
224     aMsg += TCollection_AsciiString( nbOperatorErrors );
225     MESSAGE(aMsg.ToCString());
226   }
227 }
228
229 //=============================================================================
230 /*!
231  *  GetOperatorParameters
232  */
233 //=============================================================================
234 bool GEOMImpl_IHealingOperations::GetOperatorParameters( const std::string theOperation,
235                                                          std::list<std::string>& theParams,
236                                                          std::list<std::string>& theValues )
237 {
238   ShHealOper_ShapeProcess aHealer;
239   int nbParamValueErrors( 0 );
240   std::list<std::string> aParams;
241   if ( GetParameters( theOperation, aParams ) ) {
242     for ( std::list<std::string>::iterator it = aParams.begin(); it != aParams.end(); ++it ) {
243       TCollection_AsciiString aParam( (Standard_CString)(*it).c_str() );
244       TCollection_AsciiString aValue;
245       if ( aHealer.GetParameter( aParam, aValue ) ) {
246         theParams.push_back( aParam.ToCString() );
247         theValues.push_back( aValue.ToCString() );
248       }
249       else
250         nbParamValueErrors++;
251     }
252   }
253   else
254     return false;
255
256   if ( nbParamValueErrors ) {
257     TCollection_AsciiString aMsg ("ERRORS retrieving ShapeProcess parameter values (GEOMImpl_IHealingOperations): nbParamValueErrors = ");
258     aMsg += TCollection_AsciiString( nbParamValueErrors );
259     MESSAGE(aMsg.ToCString());
260   }
261
262   return true;
263 }
264
265 //=============================================================================
266 /*!
267  *  GetParameters
268  */
269 //=============================================================================
270 bool GEOMImpl_IHealingOperations::GetParameters (const std::string theOperation,
271                                                  std::list<std::string>& theParams)
272 {
273   if ( theOperation == "SplitAngle" ) {
274     theParams.push_back( "SplitAngle.Angle" );
275     theParams.push_back( "SplitAngle.MaxTolerance" );
276
277   } else if ( theOperation == "SplitClosedFaces" ) {
278     theParams.push_back( "SplitClosedFaces.NbSplitPoints" );
279
280   } else if ( theOperation == "FixFaceSize" ) {
281     theParams.push_back( "FixFaceSize.Tolerance" );
282
283   } else if( theOperation == "DropSmallEdges" ) {
284     theParams.push_back( "DropSmallEdges.Tolerance3d" );
285
286   } else if( theOperation == "BSplineRestriction" ) {
287     theParams.push_back( "BSplineRestriction.SurfaceMode" );
288     theParams.push_back( "BSplineRestriction.Curve3dMode" );
289     theParams.push_back( "BSplineRestriction.Curve2dMode" );
290     theParams.push_back( "BSplineRestriction.Tolerance3d" );
291     theParams.push_back( "BSplineRestriction.Tolerance2d" );
292     theParams.push_back( "BSplineRestriction.RequiredDegree" );
293     theParams.push_back( "BSplineRestriction.RequiredNbSegments" );
294     theParams.push_back( "BSplineRestriction.Continuity3d" );
295     theParams.push_back( "BSplineRestriction.Continuity2d" );
296
297   } else if( theOperation == "SplitContinuity" ) {
298     theParams.push_back( "SplitContinuity.Tolerance3d" );
299     theParams.push_back( "SplitContinuity.SurfaceContinuity" );
300     theParams.push_back( "SplitContinuity.CurveContinuity" );
301
302   } else if( theOperation == "ToBezier" ) {
303     theParams.push_back( "ToBezier.SurfaceMode" );
304     theParams.push_back( "ToBezier.Curve3dMode" );
305     theParams.push_back( "ToBezier.Curve2dMode" );
306     theParams.push_back( "ToBezier.MaxTolerance" );
307
308   } else if( theOperation == "SameParameter" ) {
309     theParams.push_back( "SameParameter.Tolerance3d" );
310
311   } else if( theOperation == "FixShape" ) {
312     theParams.push_back( "FixShape.Tolerance3d" );
313     theParams.push_back( "FixShape.MaxTolerance3d" );
314
315   } else {
316     return false;
317   }
318
319   return true;
320 }
321
322 //=============================================================================
323 /*!
324  *  SuppressFaces
325  */
326 //=============================================================================
327 Handle(GEOM_Object) GEOMImpl_IHealingOperations::SuppressFaces
328        (Handle(GEOM_Object) theObject, const Handle(TColStd_HArray1OfInteger)& theFaces)
329 {
330   // set error code, check parameters
331   SetErrorCode(KO);
332
333   if (theObject.IsNull()) // if theFaces.IsNull() - it's OK, it means that ALL faces must be removed..
334     return NULL;
335
336   Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
337   if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
338
339   // Add a new object
340   Handle(GEOM_Object) aNewObject = GetEngine()->AddObject(GetDocID(), GEOM_COPY);
341
342   //Add the function
343   aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), SUPPRESS_FACES);
344
345   if (aFunction.IsNull()) return NULL;
346
347   //Check if the function is set correctly
348   if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
349
350   // prepare "data container" class IHealing
351   GEOMImpl_IHealing HI (aFunction);
352   HI.SetFaces(theFaces);
353   HI.SetOriginal(aLastFunction);
354
355   //Compute the translation
356   try {
357 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
358     OCC_CATCH_SIGNALS;
359 #endif
360     if (!GetSolver()->ComputeFunction(aFunction))
361     {
362       SetErrorCode("Healing driver failed");
363       return NULL;
364     }
365   }
366   catch (Standard_Failure)
367   {
368     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
369     SetErrorCode(aFail->GetMessageString());
370     return NULL;
371   }
372
373   //Make a Python command
374   GEOM::TPythonDump pd (aFunction);
375   pd << aNewObject << " = geompy.SuppressFaces(" << theObject << ", [";
376
377   // list of face ids
378   int i = theFaces->Lower(), nb = theFaces->Upper();
379   for ( ; i <= nb; i++)
380     pd << theFaces->Value( i ) << (( i < nb ) ? ", " : "])");
381
382   SetErrorCode(OK);
383   return aNewObject;
384 }
385
386 //=============================================================================
387 /*!
388  *  CloseContour
389  */
390 //=============================================================================
391 Handle(GEOM_Object) GEOMImpl_IHealingOperations::CloseContour
392                     (Handle(GEOM_Object) theObject,
393                      const Handle(TColStd_HArray1OfInteger)& theWires,
394                      bool isCommonVertex)
395 {
396   // set error code, check parameters
397   SetErrorCode(KO);
398
399   if (theObject.IsNull())
400   {
401     SetErrorCode("NULL object given");
402     return NULL;
403   }
404
405   Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
406   if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
407
408   // Add a new object
409   Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
410
411   //Add the function
412   aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), CLOSE_CONTOUR);
413
414   if (aFunction.IsNull()) return NULL;
415
416   //Check if the function is set correctly
417   if(aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
418
419   // prepare "data container" class IHealing
420   GEOMImpl_IHealing HI(aFunction);
421   HI.SetWires( theWires );
422   HI.SetIsCommonVertex( isCommonVertex );
423   HI.SetOriginal( aLastFunction );
424
425   //Compute the translation
426   try {
427 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
428     OCC_CATCH_SIGNALS;
429 #endif
430     if (!GetSolver()->ComputeFunction(aFunction))
431     {
432       SetErrorCode("Healing driver failed");
433       return NULL;
434     }
435   }
436   catch (Standard_Failure)
437   {
438         Handle(Standard_Failure) aFail = Standard_Failure::Caught();
439     SetErrorCode(aFail->GetMessageString());
440     return NULL;
441   }
442
443   //Make a Python command
444   GEOM::TPythonDump pd (aFunction);
445   pd << aNewObject << " = geompy.CloseContour(" << theObject << ", [";
446
447   // list of wire ids
448   if (!theWires.IsNull())
449   {
450     int i = theWires->Lower(), nb = theWires->Upper();
451     pd << theWires->Value(i++);
452     while (i <= nb)
453       pd << ", " << theWires->Value(i++);
454   }
455   pd << "], " << (int)isCommonVertex << ")";
456
457   SetErrorCode(OK);
458   return aNewObject;
459 }
460
461 //=============================================================================
462 /*!
463  *  RemoveIntWires
464  */
465 //=============================================================================
466 Handle(GEOM_Object) GEOMImpl_IHealingOperations::RemoveIntWires
467        (Handle(GEOM_Object) theObject, const Handle(TColStd_HArray1OfInteger)& theWires)
468 {
469   // set error code, check parameters
470   SetErrorCode(KO);
471
472   if (theObject.IsNull()) // if theWires is NULL it's OK, it means that ALL wires must be removed
473     return NULL;
474
475   Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
476   if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
477
478   // Add a new object
479   Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
480
481   //Add the function
482   aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), REMOVE_INT_WIRES);
483
484   if (aFunction.IsNull()) return NULL;
485
486   //Check if the function is set correctly
487   if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
488
489   // prepare "data container" class IHealing
490   GEOMImpl_IHealing HI(aFunction);
491   HI.SetWires( theWires );
492   HI.SetOriginal( aLastFunction );
493
494   //Compute the translation
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     {
501       SetErrorCode("Healing driver failed");
502       return NULL;
503     }
504   }
505   catch (Standard_Failure)
506   {
507     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
508     SetErrorCode(aFail->GetMessageString());
509     return NULL;
510   }
511
512   //Make a Python command
513   GEOM::TPythonDump pd (aFunction);
514   pd << aNewObject << " = geompy.SuppressInternalWires(" << theObject << ", [";
515
516   // list of wire ids
517   if (!theWires.IsNull()) {
518     int i = theWires->Lower(), nb = theWires->Upper();
519     for ( ; i <= nb; i++)
520       pd << theWires->Value( i ) << (( i < nb ) ? ", " : "])");
521   } else {
522     pd << "])";
523   }
524
525   SetErrorCode(OK);
526   return aNewObject;
527 }
528
529 //=============================================================================
530 /*!
531  *  FillHoles
532  */
533 //=============================================================================
534 Handle(GEOM_Object) GEOMImpl_IHealingOperations::FillHoles (Handle(GEOM_Object) theObject,
535                                                             const Handle(TColStd_HArray1OfInteger)& theWires)
536 {
537   // set error code, check parameters
538   SetErrorCode(KO);
539
540   if (theObject.IsNull()) // if theWires is NULL it's OK, it means that ALL holes must be removed
541     return NULL;
542
543   Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
544   if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
545
546   // Add a new object
547   Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
548
549   //Add the function
550   aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), FILL_HOLES);
551
552   if (aFunction.IsNull()) return NULL;
553
554   //Check if the function is set correctly
555   if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
556
557   // prepare "data container" class IHealing
558   GEOMImpl_IHealing HI(aFunction);
559   HI.SetWires( theWires );
560   HI.SetOriginal( aLastFunction );
561
562   //Compute the translation
563   try {
564 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
565     OCC_CATCH_SIGNALS;
566 #endif
567     if (!GetSolver()->ComputeFunction(aFunction))
568     {
569       SetErrorCode("Healing driver failed");
570       return NULL;
571     }
572   }
573   catch (Standard_Failure)
574   {
575         Handle(Standard_Failure) aFail = Standard_Failure::Caught();
576     SetErrorCode(aFail->GetMessageString());
577     return NULL;
578   }
579
580   //Make a Python command
581   GEOM::TPythonDump pd (aFunction);
582   pd << aNewObject << " = geompy.SuppressHoles(" << theObject << ", [";
583
584   // list of wire ids
585   if ( theWires.IsNull() )
586     pd << "])";
587   else {
588     int i = theWires->Lower(), nb = theWires->Upper();
589     for ( ; i <= nb; i++)
590       pd << theWires->Value( i ) << (( i < nb ) ? ", " : "])");
591   }
592
593   SetErrorCode(OK);
594   return aNewObject;
595 }
596
597 //=============================================================================
598 /*!
599  *  Sew
600  */
601 //=============================================================================
602 Handle(GEOM_Object) GEOMImpl_IHealingOperations::Sew (Handle(GEOM_Object) theObject,
603                                                       double theTolerance)
604 {
605   // set error code, check parameters
606   SetErrorCode(KO);
607
608   if (theObject.IsNull())
609     return NULL;
610
611   Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
612   if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
613
614   // Add a new object
615   Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
616
617   //Add the function
618   aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), SEWING);
619
620   if (aFunction.IsNull()) return NULL;
621
622   //Check if the function is set correctly
623   if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
624
625   // prepare "data container" class IHealing
626   GEOMImpl_IHealing HI(aFunction);
627   HI.SetTolerance( theTolerance );
628   HI.SetOriginal( aLastFunction );
629
630   //Compute the translation
631   try {
632 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
633     OCC_CATCH_SIGNALS;
634 #endif
635     if (!GetSolver()->ComputeFunction(aFunction))
636     {
637       SetErrorCode("Healing driver failed");
638       return NULL;
639     }
640   }
641   catch (Standard_Failure)
642   {
643         Handle(Standard_Failure) aFail = Standard_Failure::Caught();
644     SetErrorCode(aFail->GetMessageString());
645     return NULL;
646   }
647
648   //Make a Python command
649   GEOM::TPythonDump(aFunction) << aNewObject << " = geompy.Sew("
650                                << theObject << ", " << theTolerance << ")";
651
652   SetErrorCode(OK);
653   return aNewObject;
654 }
655
656 //=============================================================================
657 /*!
658  *  DivideEdge
659  */
660 //=============================================================================
661 Handle(GEOM_Object) GEOMImpl_IHealingOperations::DivideEdge (Handle(GEOM_Object) theObject,
662                                                              int theIndex,
663                                                              double theValue,
664                                                              bool isByParameter)
665 {
666   // set error code, check parameters
667   SetErrorCode(KO);
668
669   if (theObject.IsNull())
670     return NULL;
671
672   Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
673   if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
674
675   // Add a new object
676   Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
677
678   //Add the function
679   aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), DIVIDE_EDGE);
680
681   if (aFunction.IsNull()) return NULL;
682
683   //Check if the function is set correctly
684   if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
685
686   // prepare "data container" class IHealing
687   GEOMImpl_IHealing HI(aFunction);
688   HI.SetIndex( theIndex );
689   HI.SetDevideEdgeValue( theValue );
690   HI.SetIsByParameter( isByParameter );
691   HI.SetOriginal( aLastFunction );
692
693   //Compute the translation
694   try {
695 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
696     OCC_CATCH_SIGNALS;
697 #endif
698     if (!GetSolver()->ComputeFunction(aFunction))
699     {
700       SetErrorCode("Healing driver failed");
701       return NULL;
702     }
703   }
704   catch (Standard_Failure)
705   {
706         Handle(Standard_Failure) aFail = Standard_Failure::Caught();
707     SetErrorCode(aFail->GetMessageString());
708     return NULL;
709   }
710
711   //Make a Python command
712   GEOM::TPythonDump(aFunction) << aNewObject << " = geompy.DivideEdge(" << theObject
713     << ", " << theIndex << ", " << theValue << ", " << (int)isByParameter << ")";
714
715   SetErrorCode(OK);
716   return aNewObject;
717 }
718
719 //=============================================================================
720 /*!
721  *  GetFreeBoundary
722  */
723 //=============================================================================
724 bool GEOMImpl_IHealingOperations::GetFreeBoundary (Handle(GEOM_Object) theObject,
725                                                    Handle(TColStd_HSequenceOfTransient)& theClosed,
726                                                    Handle(TColStd_HSequenceOfTransient)& theOpen )
727 {
728   // set error code, check parameters
729   SetErrorCode(KO);
730
731   if ( theObject.IsNull() || theClosed.IsNull() || theOpen.IsNull() )
732     return false;
733
734   TopoDS_Shape aShape = theObject->GetValue();
735   if ( aShape.IsNull() )
736     return false;
737
738   // get free boundary shapes
739
740 #if OCC_VERSION_LARGE > 0x06030008
741   ShapeAnalysis_FreeBounds anAnalizer(aShape, Standard_False,
742                                       Standard_True, Standard_True);
743 #else
744   ShapeAnalysis_FreeBounds anAnalizer(aShape);
745 #endif
746   TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
747   TopoDS_Compound anOpen = anAnalizer.GetOpenWires();
748
749   // iterate through shapes and append them to the return sequence
750   Handle(GEOM_Object) anObj;
751   Handle(GEOM_Function) aFunction;
752   TopExp_Explorer anExp;
753   for ( anExp.Init( aClosed, TopAbs_WIRE ); anExp.More(); anExp.Next() )
754   {
755     anObj = GetEngine()->AddObject( GetDocID(), GEOM_FREE_BOUNDS );
756     aFunction = anObj->AddFunction( GEOMImpl_CopyDriver::GetID(), COPY_WITHOUT_REF );
757     TopoDS_Shape aValueShape = anExp.Current();
758     aFunction->SetValue( aValueShape );
759     theClosed->Append(anObj);
760   }
761   for ( anExp.Init( anOpen, TopAbs_WIRE ); anExp.More(); anExp.Next() )
762   {
763     anObj = GetEngine()->AddObject( GetDocID(), GEOM_FREE_BOUNDS );
764     aFunction = anObj->AddFunction( GEOMImpl_CopyDriver::GetID(), COPY_WITHOUT_REF );
765     TopoDS_Shape aValueShape = anExp.Current();
766     aFunction->SetValue( aValueShape );
767     theOpen->Append(anObj);
768   }
769
770   if(!aFunction.IsNull()) {
771
772     //Make a Python command
773     GEOM::TPythonDump pd (aFunction);
774
775     Standard_Integer i, aLen = theClosed->Length();
776     if (aLen > 0) {
777       pd << "(isDone, [";
778       for (i = 1; i <= aLen; i++) {
779         Handle(GEOM_Object) anObj_i = Handle(GEOM_Object)::DownCast(theClosed->Value(i));
780         pd << anObj_i << ((i < aLen) ? ", " : "");
781       }
782       pd << "], ";
783     } else {
784       pd << "(isDone, empty_list, ";
785     }
786
787     aLen = theOpen->Length();
788     if (aLen > 0) {
789       pd << "[";
790       for (i = 1; i <= aLen; i++) {
791         Handle(GEOM_Object) anObj_i = Handle(GEOM_Object)::DownCast(theOpen->Value(i));
792         pd << anObj_i << ((i < aLen) ? ", " : "");
793       }
794       pd << "]";
795     } else {
796       pd << "empty_list";
797     }
798
799     pd << ") = geompy.GetFreeBoundary(" << theObject << ")";
800   }
801
802   SetErrorCode(OK);
803   return true;
804 }
805
806
807 //=============================================================================
808 /*!
809  *  ChangeOrientation
810  */
811 //=============================================================================
812 Handle(GEOM_Object) GEOMImpl_IHealingOperations::ChangeOrientation (Handle(GEOM_Object) theObject)
813 {
814   // set error code, check parameters
815   SetErrorCode(KO);
816
817   if (theObject.IsNull())
818     return NULL;
819
820   if (!theObject->IsMainShape()) {
821     SetErrorCode("Sub shape cannot be transformed - need to create a copy");
822     return NULL;
823   }
824
825   Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
826   if (aLastFunction.IsNull())
827     return NULL; //There is no function which creates an object to be processed
828
829   //Add the function
830   aFunction = theObject->AddFunction(GEOMImpl_HealingDriver::GetID(), CHANGE_ORIENTATION);
831
832   if (aFunction.IsNull())
833     return NULL;
834
835   //Check if the function is set correctly
836   if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
837
838   // prepare "data container" class IHealing
839   GEOMImpl_IHealing HI(aFunction);
840   HI.SetOriginal( aLastFunction );
841
842   //Compute the translation
843   try {
844 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
845     OCC_CATCH_SIGNALS;
846 #endif
847     if (!GetSolver()->ComputeFunction(aFunction)) {
848       SetErrorCode("Healing driver failed");
849       return NULL;
850     }
851   }
852   catch (Standard_Failure) {
853     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
854     SetErrorCode(aFail->GetMessageString());
855     return NULL;
856   }
857
858   //Make a Python command
859   GEOM::TPythonDump(aFunction) << "geompy.ChangeOrientationShell("
860                                << theObject << ")";
861
862   SetErrorCode(OK);
863   return theObject;
864 }
865
866 //=============================================================================
867 /*!
868  *  ChangeOrientationCopy
869  */
870 //=============================================================================
871 Handle(GEOM_Object) GEOMImpl_IHealingOperations::ChangeOrientationCopy (Handle(GEOM_Object) theObject)
872 {
873   // set error code, check parameters
874   SetErrorCode(KO);
875
876   if (theObject.IsNull())
877     return NULL;
878
879   Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
880   if (aLastFunction.IsNull())
881     return NULL; //There is no function which creates an object to be processed
882
883   // Add a new object
884   Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), theObject->GetType() );
885
886   //Add the function
887   aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), CHANGE_ORIENTATION);
888
889   if (aFunction.IsNull())
890     return NULL;
891
892   //Check if the function is set correctly
893   if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
894
895   // prepare "data container" class IHealing
896   GEOMImpl_IHealing HI(aFunction);
897   HI.SetOriginal( aLastFunction );
898
899   //Compute the translation
900   try {
901 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
902     OCC_CATCH_SIGNALS;
903 #endif
904     if (!GetSolver()->ComputeFunction(aFunction)) {
905       SetErrorCode("Healing driver failed");
906       return NULL;
907     }
908   }
909   catch (Standard_Failure) {
910     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
911     SetErrorCode(aFail->GetMessageString());
912     return NULL;
913   }
914
915   //Make a Python command
916   GEOM::TPythonDump(aFunction) << aNewObject << " = geompy.ChangeOrientationShellCopy("
917                                << theObject << ")";
918
919   SetErrorCode(OK);
920   return aNewObject;
921 }
922
923 //=============================================================================
924 /*!
925  *  LimitTolerance
926  */
927 //=============================================================================
928 Handle(GEOM_Object) GEOMImpl_IHealingOperations::LimitTolerance (Handle(GEOM_Object) theObject,
929                                                                  double theTolerance)
930 {
931   // Set error code, check parameters
932   SetErrorCode(KO);
933
934   if (theObject.IsNull())
935     return NULL;
936
937   Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
938   if (aLastFunction.IsNull())
939     return NULL; // There is no function which creates an object to be processed
940
941   // Add a new object
942   Handle(GEOM_Object) aNewObject = GetEngine()->AddObject(GetDocID(), theObject->GetType());
943
944   // Add the function
945   aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), LIMIT_TOLERANCE);
946
947   if (aFunction.IsNull())
948     return NULL;
949
950   // Check if the function is set correctly
951   if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
952
953   // Prepare "data container" class IHealing
954   GEOMImpl_IHealing HI (aFunction);
955   HI.SetOriginal(aLastFunction);
956   HI.SetTolerance(theTolerance);
957
958   // Compute
959   try {
960 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
961     OCC_CATCH_SIGNALS;
962 #endif
963     if (!GetSolver()->ComputeFunction(aFunction)) {
964       SetErrorCode("Healing driver failed");
965       return NULL;
966     }
967   }
968   catch (Standard_Failure) {
969     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
970     SetErrorCode(aFail->GetMessageString());
971     return NULL;
972   }
973
974   // Make a Python command
975   GEOM::TPythonDump(aFunction) << aNewObject << " = geompy.LimitTolerance("
976                                << theObject << ", " << theTolerance << ")";
977
978   SetErrorCode(OK);
979   return aNewObject;
980 }