Salome HOME
PAL7508: Development of GetInPlace() functionality
[modules/geom.git] / src / GEOMImpl / GEOMImpl_IHealingOperations.cxx
1 using namespace std;
2
3 #include "GEOMImpl_IHealingOperations.hxx"
4
5 #include "GEOMImpl_HealingDriver.hxx"
6 #include "GEOMImpl_Types.hxx"
7 #include "GEOMImpl_IHealing.hxx"
8 #include "GEOMImpl_CopyDriver.hxx"
9
10 #include "ShHealOper_ShapeProcess.hxx"
11
12 #include "utilities.h"
13 #include "OpUtil.hxx"
14 #include "Utils_ExceptHandlers.hxx"
15
16 #include <ShapeAnalysis_FreeBounds.hxx>
17
18 #include <TopoDS_Compound.hxx>
19 #include <TopExp_Explorer.hxx>
20
21 #include <TColStd_HArray1OfExtendedString.hxx>
22 #include <TColStd_HSequenceOfTransient.hxx>
23 #include <TCollection_AsciiString.hxx>
24
25 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
26
27
28 //=============================================================================
29 /*!
30  *   constructor:
31  */
32 //=============================================================================
33
34 GEOMImpl_IHealingOperations::GEOMImpl_IHealingOperations (GEOM_Engine* theEngine, int theDocID)
35 : GEOM_IOperations(theEngine, theDocID)
36 {
37   MESSAGE("GEOMImpl_IHealingOperations::GEOMImpl_IHealingOperations");
38 }
39
40 //=============================================================================
41 /*!
42  *  destructor
43  */
44 //=============================================================================
45
46 GEOMImpl_IHealingOperations::~GEOMImpl_IHealingOperations()
47 {
48   MESSAGE("GEOMImpl_IHealingOperations::~GEOMImpl_IHealingOperations");
49 }
50
51
52 //=============================================================================
53 /*!
54  *  ShapeProcess
55  */
56 //=============================================================================
57 Handle(GEOM_Object) GEOMImpl_IHealingOperations::ShapeProcess (Handle(GEOM_Object) theObject,
58                                   const Handle(TColStd_HArray1OfExtendedString)& theOperators,
59                                   const Handle(TColStd_HArray1OfExtendedString)& theParams,
60                                   const Handle(TColStd_HArray1OfExtendedString)& theValues)
61 {
62   // set error code, check parameters
63   SetErrorCode(KO);
64
65   if (theObject.IsNull())
66     return NULL;
67
68   if (theOperators.IsNull() || theOperators->Length() <= 0) {
69     SetErrorCode("No operators requested");
70     return NULL;
71   }
72
73   Standard_Integer nbParams = 0, nbValues = 0;
74   if (!theParams.IsNull()) {
75     nbParams = theParams->Length();
76   }
77   if (!theValues.IsNull()) {
78     nbValues = theValues->Length();
79   }
80
81   if (nbParams != nbValues) {
82     SetErrorCode("Number of parameter values must be equal to the number of parameters");
83     return NULL;
84   }
85
86   Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
87   if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
88
89   // Add a new object
90   Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
91
92   //Add the function
93   aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), SHAPE_PROCESS);
94
95   if (aFunction.IsNull()) return NULL;
96
97   //Check if the function is set correctly
98   if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
99
100   // prepare "data container" class IHealing
101   GEOMImpl_IHealing HI(aFunction);
102   HI.SetOriginal(aLastFunction);
103   HI.SetOperators( theOperators );
104   if (nbParams > 0) {
105     HI.SetParameters( theParams );
106     HI.SetValues( theValues );
107   }
108
109   //Compute the translation
110   try
111   {
112     if (!GetSolver()->ComputeFunction(aFunction))
113     {
114       SetErrorCode("Shape Healing algorithm failed");
115       return NULL;
116     }
117   }
118   catch (Standard_Failure)
119   {
120     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
121     SetErrorCode(aFail->GetMessageString());
122     return NULL;
123   }
124
125   //Make a Python command
126   // ...
127   // ... missing ...
128
129   SetErrorCode(OK);
130   return aNewObject;
131 }
132
133 //=============================================================================
134 /*!
135  *  ShapeProcess
136  */
137 //=============================================================================
138 void GEOMImpl_IHealingOperations::GetShapeProcessParameters (list<string>& theOperations,
139                                                              list<string>& theParams,
140                                                              list<string>& theValues)
141 {
142   ShHealOper_ShapeProcess aHealer;
143   TColStd_SequenceOfAsciiString anOperators;
144   int nbOperatorErrors( 0 );
145   if ( aHealer.GetOperators( anOperators ) )
146   {
147     for ( Standard_Integer i = 1; i <= anOperators.Length(); i++ )
148     {
149       string anOperation = anOperators.Value( i ).ToCString();
150       if ( GetOperatorParameters( anOperation, theParams, theValues ) )
151         theOperations.push_back( anOperation );
152       else
153         nbOperatorErrors++;
154     }
155   }
156   else
157   {
158     SetErrorCode("ERROR retrieving operators (GEOMImpl_IHealingOperations)");
159   }
160
161   if ( nbOperatorErrors ) {
162     TCollection_AsciiString aMsg ("ERRORS retrieving ShapeProcess parameters (GEOMImpl_IHealingOperations): nbOperatorErrors = ");
163     aMsg += TCollection_AsciiString( nbOperatorErrors );
164     MESSAGE(aMsg.ToCString());
165   }
166 }
167
168 //=============================================================================
169 /*!
170  *  GetOperatorParameters
171  */
172 //=============================================================================
173 bool GEOMImpl_IHealingOperations::GetOperatorParameters( const string theOperation, 
174                                                          list<string>& theParams,
175                                                          list<string>& theValues )
176 {
177   ShHealOper_ShapeProcess aHealer;
178   int nbParamValueErrors( 0 );
179   list<string> aParams;
180   if ( GetParameters( theOperation, aParams ) ) {
181     for ( list<string>::iterator it = aParams.begin(); it != aParams.end(); ++it ) {
182       TCollection_AsciiString aParam( (Standard_CString)(*it).c_str() );
183       TCollection_AsciiString aValue;
184       if ( aHealer.GetParameter( aParam, aValue ) ) {
185         theParams.push_back( aParam.ToCString() );
186         theValues.push_back( aValue.ToCString() );
187       }
188       else
189         nbParamValueErrors++;
190     }
191   }
192   else
193     return false;
194
195   if ( nbParamValueErrors ) {
196     TCollection_AsciiString aMsg ("ERRORS retrieving ShapeProcess parameter values (GEOMImpl_IHealingOperations): nbParamValueErrors = ");
197     aMsg += TCollection_AsciiString( nbParamValueErrors );
198     MESSAGE(aMsg.ToCString());
199   }
200
201   return true;
202 }
203
204 //=============================================================================
205 /*!
206  *  GetParameters
207  */
208 //=============================================================================
209 bool GEOMImpl_IHealingOperations::GetParameters (const string theOperation,
210                                                  list<string>& theParams)
211 {
212   if ( theOperation == "SplitAngle" ) {
213     theParams.push_back( "SplitAngle.Angle" );
214     theParams.push_back( "SplitAngle.MaxTolerance" );
215
216   } else if ( theOperation == "SplitClosedFaces" ) {
217     theParams.push_back( "SplitClosedFaces.NbSplitPoints" );
218
219   } else if ( theOperation == "FixFaceSize" ) {
220     theParams.push_back( "FixFaceSize.Tolerance" );
221
222   } else if( theOperation == "DropSmallEdges" ) {
223     theParams.push_back( "DropSmallEdges.Tolerance3d" );
224
225   } else if( theOperation == "BSplineRestriction" ) {
226     theParams.push_back( "BSplineRestriction.SurfaceMode" );
227     theParams.push_back( "BSplineRestriction.Curve3dMode" );
228     theParams.push_back( "BSplineRestriction.Curve2dMode" );
229     theParams.push_back( "BSplineRestriction.Tolerance3d" );
230     theParams.push_back( "BSplineRestriction.Tolerance2d" );
231     theParams.push_back( "BSplineRestriction.RequiredDegree" );
232     theParams.push_back( "BSplineRestriction.RequiredNbSegments" );
233     theParams.push_back( "BSplineRestriction.Continuity3d" );
234     theParams.push_back( "BSplineRestriction.Continuity2d" );
235
236   } else if( theOperation == "SplitContinuity" ) {
237     theParams.push_back( "SplitContinuity.Tolerance3d" );
238     theParams.push_back( "SplitContinuity.SurfaceContinuity" );
239     theParams.push_back( "SplitContinuity.CurveContinuity" );
240
241   } else if( theOperation == "ToBezier" ) {
242     theParams.push_back( "ToBezier.SurfaceMode" );
243     theParams.push_back( "ToBezier.Curve3dMode" );
244     theParams.push_back( "ToBezier.Curve2dMode" );
245     theParams.push_back( "ToBezier.MaxTolerance" );
246
247   } else if( theOperation == "SameParameter" ) {
248     theParams.push_back( "SameParameter.Tolerance3d" );
249
250   } else if( theOperation == "FixShape" ) {
251     theParams.push_back( "FixShape.Tolerance3d" );
252     theParams.push_back( "FixShape.MaxTolerance3d" );
253
254   } else {
255     return false;
256   }
257
258   return true;
259 }
260
261 //=============================================================================
262 /*!
263  *  SuppressFaces
264  */
265 //=============================================================================
266 Handle(GEOM_Object) GEOMImpl_IHealingOperations::SuppressFaces (Handle(GEOM_Object) theObject,
267                                                                 const Handle(TColStd_HArray1OfInteger)& theFaces)
268 {
269   // set error code, check parameters
270   SetErrorCode(KO);
271
272   if ( theObject.IsNull() ) // if theFaces.IsNull() - it's OK, it means that ALL faces must be removed..
273     return NULL;
274
275   Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
276   if(aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
277
278   // Add a new object
279   Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
280
281   //Add the function
282   aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), SUPPRESS_FACES);
283
284   if(aFunction.IsNull()) return NULL;
285
286   //Check if the function is set correctly
287   if(aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
288
289   // prepare "data container" class IHealing
290   GEOMImpl_IHealing HI(aFunction);
291   HI.SetFaces( theFaces );
292   HI.SetOriginal( aLastFunction );
293
294   //Compute the translation
295   try
296   {
297     if (!GetSolver()->ComputeFunction(aFunction))
298     {
299       SetErrorCode("Healing driver failed");
300       return NULL;
301     }
302   }
303   catch (Standard_Failure)
304   {
305         Handle(Standard_Failure) aFail = Standard_Failure::Caught();
306     SetErrorCode(aFail->GetMessageString());
307     return NULL;
308   }
309
310   //Make a Python command
311   // ...
312   // ... missing ...
313
314   SetErrorCode(OK);
315   return aNewObject;
316 }
317
318
319 //=============================================================================
320 /*!
321  *  CloseContour
322  */
323 //=============================================================================
324 Handle(GEOM_Object) GEOMImpl_IHealingOperations::CloseContour (Handle(GEOM_Object) theObject,
325                                                                const Handle(TColStd_HArray1OfInteger)& theWires,
326                                                                bool isCommonVertex)
327 {
328   // set error code, check parameters
329   SetErrorCode(KO);
330
331   if (theObject.IsNull())
332     return NULL;
333
334   Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
335   if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
336
337   // Add a new object
338   Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
339
340   //Add the function
341   aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), CLOSE_CONTOUR);
342
343   if (aFunction.IsNull()) return NULL;
344
345   //Check if the function is set correctly
346   if(aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
347
348   // prepare "data container" class IHealing
349   GEOMImpl_IHealing HI(aFunction);
350   HI.SetWires( theWires );
351   HI.SetIsCommonVertex( isCommonVertex );
352   HI.SetOriginal( aLastFunction );
353
354   //Compute the translation
355   try
356   {
357     if (!GetSolver()->ComputeFunction(aFunction))
358     {
359       SetErrorCode("Healing driver failed");
360       return NULL;
361     }
362   }
363   catch (Standard_Failure)
364   {
365         Handle(Standard_Failure) aFail = Standard_Failure::Caught();
366     SetErrorCode(aFail->GetMessageString());
367     return NULL;
368   }
369
370   //Make a Python command
371   // ...
372   // ... missing ...
373
374   SetErrorCode(OK);
375   return aNewObject;
376 }
377
378 //=============================================================================
379 /*!
380  *  RemoveIntWires
381  */
382 //=============================================================================
383 Handle(GEOM_Object) GEOMImpl_IHealingOperations::RemoveIntWires (Handle(GEOM_Object) theObject,
384                                                                  const Handle(TColStd_HArray1OfInteger)& theWires)
385 {
386   // set error code, check parameters
387   SetErrorCode(KO);
388
389   if (theObject.IsNull()) // if theWires is NULL it's OK, it means that ALL wires must be removed
390     return NULL;
391
392   Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
393   if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
394
395   // Add a new object
396   Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
397
398   //Add the function
399   aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), REMOVE_INT_WIRES);
400
401   if (aFunction.IsNull()) return NULL;
402
403   //Check if the function is set correctly
404   if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
405
406   // prepare "data container" class IHealing
407   GEOMImpl_IHealing HI(aFunction);
408   HI.SetWires( theWires );
409   HI.SetOriginal( aLastFunction );
410
411   //Compute the translation
412   try
413   {
414     if (!GetSolver()->ComputeFunction(aFunction))
415     {
416       SetErrorCode("Healing driver failed");
417       return NULL;
418     }
419   }
420   catch (Standard_Failure)
421   {
422     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
423     SetErrorCode(aFail->GetMessageString());
424     return NULL;
425   }
426
427   //Make a Python command
428   // ...
429   // ... missing ...
430
431   SetErrorCode(OK);
432   return aNewObject;
433 }
434
435 //=============================================================================
436 /*!
437  *  FillHoles
438  */
439 //=============================================================================
440 Handle(GEOM_Object) GEOMImpl_IHealingOperations::FillHoles (Handle(GEOM_Object) theObject,
441                                                             const Handle(TColStd_HArray1OfInteger)& theWires)
442 {
443   // set error code, check parameters
444   SetErrorCode(KO);
445
446   if (theObject.IsNull()) // if theWires is NULL it's OK, it means that ALL holes must be removed
447     return NULL;
448
449   Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
450   if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
451
452   // Add a new object
453   Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
454
455   //Add the function
456   aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), FILL_HOLES);
457
458   if (aFunction.IsNull()) return NULL;
459
460   //Check if the function is set correctly
461   if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
462
463   // prepare "data container" class IHealing
464   GEOMImpl_IHealing HI(aFunction);
465   HI.SetWires( theWires );
466   HI.SetOriginal( aLastFunction );
467
468   //Compute the translation
469   try
470   {
471     if (!GetSolver()->ComputeFunction(aFunction))
472     {
473       SetErrorCode("Healing driver failed");
474       return NULL;
475     }
476   }
477   catch (Standard_Failure)
478   {
479         Handle(Standard_Failure) aFail = Standard_Failure::Caught();
480     SetErrorCode(aFail->GetMessageString());
481     return NULL;
482   }
483
484   //Make a Python command
485   // ...
486   // ... missing ...
487
488   SetErrorCode(OK);
489   return aNewObject;
490 }
491
492 //=============================================================================
493 /*!
494  *  Sew
495  */
496 //=============================================================================
497 Handle(GEOM_Object) GEOMImpl_IHealingOperations::Sew (Handle(GEOM_Object) theObject,
498                                                       double theTolerance)
499 {
500   // set error code, check parameters
501   SetErrorCode(KO);
502
503   if (theObject.IsNull())
504     return NULL;
505
506   Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
507   if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
508
509   // Add a new object
510   Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
511
512   //Add the function
513   aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), SEWING);
514
515   if (aFunction.IsNull()) return NULL;
516
517   //Check if the function is set correctly
518   if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
519
520   // prepare "data container" class IHealing
521   GEOMImpl_IHealing HI(aFunction);
522   HI.SetTolerance( theTolerance );
523   HI.SetOriginal( aLastFunction );
524
525   //Compute the translation
526   try
527   {
528     if (!GetSolver()->ComputeFunction(aFunction))
529     {
530       SetErrorCode("Healing driver failed");
531       return NULL;
532     }
533   }
534   catch (Standard_Failure)
535   {
536         Handle(Standard_Failure) aFail = Standard_Failure::Caught();
537     SetErrorCode(aFail->GetMessageString());
538     return NULL;
539   }
540
541   //Make a Python command
542   // ...
543   // ... missing ...
544
545   SetErrorCode(OK);
546   return aNewObject;
547 }
548
549 //=============================================================================
550 /*!
551  *  DivideEdge
552  */
553 //=============================================================================
554 Handle(GEOM_Object) GEOMImpl_IHealingOperations::DivideEdge (Handle(GEOM_Object) theObject,
555                                                              int theIndex,
556                                                              double theValue,
557                                                              bool isByParameter)
558 {
559   // set error code, check parameters
560   SetErrorCode(KO);
561
562   if (theObject.IsNull())
563     return NULL;
564
565   Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
566   if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
567
568   // Add a new object
569   Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
570
571   //Add the function
572   aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), DIVIDE_EDGE);
573
574   if (aFunction.IsNull()) return NULL;
575
576   //Check if the function is set correctly
577   if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
578
579   // prepare "data container" class IHealing
580   GEOMImpl_IHealing HI(aFunction);
581   HI.SetIndex( theIndex );
582   HI.SetDevideEdgeValue( theValue );
583   HI.SetIsByParameter( isByParameter );
584   HI.SetOriginal( aLastFunction );
585
586   //Compute the translation
587   try
588   {
589     if (!GetSolver()->ComputeFunction(aFunction))
590     {
591       SetErrorCode("Healing driver failed");
592       return NULL;
593     }
594   }
595   catch (Standard_Failure)
596   {
597         Handle(Standard_Failure) aFail = Standard_Failure::Caught();
598     SetErrorCode(aFail->GetMessageString());
599     return NULL;
600   }
601
602   //Make a Python command
603   // ...
604   // ... missing ...
605
606   SetErrorCode(OK);
607   return aNewObject;
608 }
609
610 //=============================================================================
611 /*!
612  *  GetFreeBoundary
613  */
614 //=============================================================================
615 bool GEOMImpl_IHealingOperations::GetFreeBoundary (Handle(GEOM_Object) theObject,
616                                                    Handle(TColStd_HSequenceOfTransient)& theClosed,
617                                                    Handle(TColStd_HSequenceOfTransient)& theOpen )
618 {
619   // set error code, check parameters
620   SetErrorCode(KO);
621
622   if ( theObject.IsNull() || theClosed.IsNull() || theOpen.IsNull() )
623     return false;
624
625   TopoDS_Shape aShape = theObject->GetValue();
626   if ( aShape.IsNull() )
627     return false;
628
629   // get free boundary shapes
630   ShapeAnalysis_FreeBounds anAnalizer( aShape );
631   TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
632   TopoDS_Compound anOpen = anAnalizer.GetOpenWires();
633
634   // iterate through shapes and append them to the return sequence
635   Handle(GEOM_Object) anObj;
636   Handle(GEOM_Function) aFunction;
637   TopExp_Explorer anExp;
638   for ( anExp.Init( aClosed, TopAbs_WIRE ); anExp.More(); anExp.Next() )
639   {
640     anObj = GetEngine()->AddObject( GetDocID(), GEOM_FREE_BOUNDS );
641     aFunction = anObj->AddFunction( GEOMImpl_CopyDriver::GetID(), COPY_WITHOUT_REF );
642     TopoDS_Shape aValueShape = anExp.Current();
643     aFunction->SetValue( aValueShape );
644     theClosed->Append(anObj);
645   }
646   for ( anExp.Init( anOpen, TopAbs_WIRE ); anExp.More(); anExp.Next() )
647   {
648     anObj = GetEngine()->AddObject( GetDocID(), GEOM_FREE_BOUNDS );
649     aFunction = anObj->AddFunction( GEOMImpl_CopyDriver::GetID(), COPY_WITHOUT_REF );
650     TopoDS_Shape aValueShape = anExp.Current();
651     aFunction->SetValue( aValueShape );
652     theOpen->Append(anObj);
653   }
654
655   SetErrorCode(OK);
656   return true;
657 }