]> SALOME platform Git repositories - modules/geom.git/blob - src/GEOMImpl/GEOMImpl_IHealingOperations.cxx
Salome HOME
Merge with OCC_development_01
[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 ), nbParamValueErrors( 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       theOperations.push_back( anOperation );
151       list<string> aParams, aValues;
152       if ( GetParameters( anOperation, aParams ) )
153       {
154         for ( list<string>::iterator it = aParams.begin(); it != aParams.end(); ++it )
155         {
156           TCollection_AsciiString aParam( (Standard_CString)(*it).c_str() );
157           TCollection_AsciiString aValue;
158           if ( aHealer.GetParameter( aParam, aValue ) )
159           {
160             theParams.push_back( aParam.ToCString() );
161             theValues.push_back( aValue.ToCString() );
162           }
163           else
164             nbParamValueErrors++;
165         }
166       }
167       else
168         nbOperatorErrors++;
169     }
170   }
171   else
172   {
173     SetErrorCode("ERROR retrieving operators (GEOMImpl_IHealingOperations)");
174   }
175
176   if (nbOperatorErrors || nbParamValueErrors) {
177     TCollection_AsciiString aMsg ("ERRORS retrieving ShapeProcess parameters (GEOMImpl_IHealingOperations): nbOperatorErrors = ");
178     aMsg += TCollection_AsciiString(nbOperatorErrors);
179     aMsg += " ,nbParamValueErrors = ";
180     aMsg += TCollection_AsciiString(nbParamValueErrors);
181     MESSAGE(aMsg.ToCString());
182   }
183 }
184
185 //=============================================================================
186 /*!
187  *  GetParameters
188  */
189 //=============================================================================
190 bool GEOMImpl_IHealingOperations::GetParameters (const string theOperation,
191                                                  list<string>& theParams)
192 {
193   if ( theOperation == "SplitAngle" ) {
194     theParams.push_back( "SplitAngle.Angle" );
195     theParams.push_back( "SplitAngle.MaxTolerance" );
196
197   } else if ( theOperation == "SplitClosedFaces" ) {
198     theParams.push_back( "SplitClosedFaces.NbSplitPoints" );
199
200   } else if ( theOperation == "FixFaceSize" ) {
201     theParams.push_back( "FixFaceSize.Tolerance" );
202
203   } else if( theOperation == "DropSmallEdges" ) {
204     theParams.push_back( "DropSmallEdges.Tolerance3d" );
205
206   } else if( theOperation == "BSplineRestriction" ) {
207     theParams.push_back( "BSplineRestriction.SurfaceMode" );
208     theParams.push_back( "BSplineRestriction.Curve3dMode" );
209     theParams.push_back( "BSplineRestriction.Curve2dMode" );
210     theParams.push_back( "BSplineRestriction.Tolerance3d" );
211     theParams.push_back( "BSplineRestriction.Tolerance2d" );
212     theParams.push_back( "BSplineRestriction.RequiredDegree" );
213     theParams.push_back( "BSplineRestriction.RequiredNbSegments" );
214     theParams.push_back( "BSplineRestriction.Continuity3d" );
215     theParams.push_back( "BSplineRestriction.Continuity2d" );
216
217   } else if( theOperation == "SplitContinuity" ) {
218     theParams.push_back( "SplitContinuity.Tolerance3d" );
219     theParams.push_back( "SplitContinuity.SurfaceContinuity" );
220     theParams.push_back( "SplitContinuity.CurveContinuity" );
221
222   } else if( theOperation == "ToBezier" ) {
223     theParams.push_back( "ToBezier.SurfaceMode" );
224     theParams.push_back( "ToBezier.Curve3dMode" );
225     theParams.push_back( "ToBezier.Curve2dMode" );
226     theParams.push_back( "ToBezier.MaxTolerance" );
227
228   } else if( theOperation == "SameParameter" ) {
229     theParams.push_back( "SameParameter.Tolerance3d" );
230
231   } else if( theOperation == "FixShape" ) {
232     theParams.push_back( "FixShape.Tolerance3d" );
233     theParams.push_back( "FixShape.MaxTolerance3d" );
234
235   } else {
236     return false;
237   }
238
239   return true;
240 }
241
242 //=============================================================================
243 /*!
244  *  SuppressFaces
245  */
246 //=============================================================================
247 Handle(GEOM_Object) GEOMImpl_IHealingOperations::SuppressFaces (Handle(GEOM_Object) theObject,
248                                                                 const Handle(TColStd_HArray1OfInteger)& theFaces)
249 {
250   // set error code, check parameters
251   SetErrorCode(KO);
252
253   if ( theObject.IsNull() ) // if theFaces.IsNull() - it's OK, it means that ALL faces must be removed..
254     return NULL;
255
256   Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
257   if(aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
258
259   // Add a new object
260   Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
261
262   //Add the function
263   aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), SUPPRESS_FACES);
264
265   if(aFunction.IsNull()) return NULL;
266
267   //Check if the function is set correctly
268   if(aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
269
270   // prepare "data container" class IHealing
271   GEOMImpl_IHealing HI(aFunction);
272   HI.SetFaces( theFaces );
273   HI.SetOriginal( aLastFunction );
274
275   //Compute the translation
276   try
277   {
278     if (!GetSolver()->ComputeFunction(aFunction))
279     {
280       SetErrorCode("Healing driver failed");
281       return NULL;
282     }
283   }
284   catch (Standard_Failure)
285   {
286         Handle(Standard_Failure) aFail = Standard_Failure::Caught();
287     SetErrorCode(aFail->GetMessageString());
288     return NULL;
289   }
290
291   //Make a Python command
292   // ...
293   // ... missing ...
294
295   SetErrorCode(OK);
296   return aNewObject;
297 }
298
299
300 //=============================================================================
301 /*!
302  *  CloseContour
303  */
304 //=============================================================================
305 Handle(GEOM_Object) GEOMImpl_IHealingOperations::CloseContour (Handle(GEOM_Object) theObject,
306                                                                const Handle(TColStd_HArray1OfInteger)& theWires,
307                                                                bool isCommonVertex)
308 {
309   // set error code, check parameters
310   SetErrorCode(KO);
311
312   if (theObject.IsNull())
313     return NULL;
314
315   Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
316   if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
317
318   // Add a new object
319   Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
320
321   //Add the function
322   aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), CLOSE_CONTOUR);
323
324   if (aFunction.IsNull()) return NULL;
325
326   //Check if the function is set correctly
327   if(aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
328
329   // prepare "data container" class IHealing
330   GEOMImpl_IHealing HI(aFunction);
331   HI.SetWires( theWires );
332   HI.SetIsCommonVertex( isCommonVertex );
333   HI.SetOriginal( aLastFunction );
334
335   //Compute the translation
336   try
337   {
338     if (!GetSolver()->ComputeFunction(aFunction))
339     {
340       SetErrorCode("Healing driver failed");
341       return NULL;
342     }
343   }
344   catch (Standard_Failure)
345   {
346         Handle(Standard_Failure) aFail = Standard_Failure::Caught();
347     SetErrorCode(aFail->GetMessageString());
348     return NULL;
349   }
350
351   //Make a Python command
352   // ...
353   // ... missing ...
354
355   SetErrorCode(OK);
356   return aNewObject;
357 }
358
359 //=============================================================================
360 /*!
361  *  RemoveIntWires
362  */
363 //=============================================================================
364 Handle(GEOM_Object) GEOMImpl_IHealingOperations::RemoveIntWires (Handle(GEOM_Object) theObject,
365                                                                  const Handle(TColStd_HArray1OfInteger)& theWires)
366 {
367   // set error code, check parameters
368   SetErrorCode(KO);
369
370   if (theObject.IsNull()) // if theWires is NULL it's OK, it means that ALL wires must be removed
371     return NULL;
372
373   Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
374   if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
375
376   // Add a new object
377   Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
378
379   //Add the function
380   aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), REMOVE_INT_WIRES);
381
382   if (aFunction.IsNull()) return NULL;
383
384   //Check if the function is set correctly
385   if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
386
387   // prepare "data container" class IHealing
388   GEOMImpl_IHealing HI(aFunction);
389   HI.SetWires( theWires );
390   HI.SetOriginal( aLastFunction );
391
392   //Compute the translation
393   try
394   {
395     if (!GetSolver()->ComputeFunction(aFunction))
396     {
397       SetErrorCode("Healing driver failed");
398       return NULL;
399     }
400   }
401   catch (Standard_Failure)
402   {
403     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
404     SetErrorCode(aFail->GetMessageString());
405     return NULL;
406   }
407
408   //Make a Python command
409   // ...
410   // ... missing ...
411
412   SetErrorCode(OK);
413   return aNewObject;
414 }
415
416 //=============================================================================
417 /*!
418  *  FillHoles
419  */
420 //=============================================================================
421 Handle(GEOM_Object) GEOMImpl_IHealingOperations::FillHoles (Handle(GEOM_Object) theObject,
422                                                             const Handle(TColStd_HArray1OfInteger)& theWires)
423 {
424   // set error code, check parameters
425   SetErrorCode(KO);
426
427   if (theObject.IsNull()) // if theWires is NULL it's OK, it means that ALL holes must be removed
428     return NULL;
429
430   Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
431   if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
432
433   // Add a new object
434   Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
435
436   //Add the function
437   aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), FILL_HOLES);
438
439   if (aFunction.IsNull()) return NULL;
440
441   //Check if the function is set correctly
442   if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
443
444   // prepare "data container" class IHealing
445   GEOMImpl_IHealing HI(aFunction);
446   HI.SetWires( theWires );
447   HI.SetOriginal( aLastFunction );
448
449   //Compute the translation
450   try
451   {
452     if (!GetSolver()->ComputeFunction(aFunction))
453     {
454       SetErrorCode("Healing driver failed");
455       return NULL;
456     }
457   }
458   catch (Standard_Failure)
459   {
460         Handle(Standard_Failure) aFail = Standard_Failure::Caught();
461     SetErrorCode(aFail->GetMessageString());
462     return NULL;
463   }
464
465   //Make a Python command
466   // ...
467   // ... missing ...
468
469   SetErrorCode(OK);
470   return aNewObject;
471 }
472
473 //=============================================================================
474 /*!
475  *  Sew
476  */
477 //=============================================================================
478 Handle(GEOM_Object) GEOMImpl_IHealingOperations::Sew (Handle(GEOM_Object) theObject,
479                                                       double theTolerance)
480 {
481   // set error code, check parameters
482   SetErrorCode(KO);
483
484   if (theObject.IsNull())
485     return NULL;
486
487   Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
488   if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
489
490   // Add a new object
491   Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
492
493   //Add the function
494   aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), SEWING);
495
496   if (aFunction.IsNull()) return NULL;
497
498   //Check if the function is set correctly
499   if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
500
501   // prepare "data container" class IHealing
502   GEOMImpl_IHealing HI(aFunction);
503   HI.SetTolerance( theTolerance );
504   HI.SetOriginal( aLastFunction );
505
506   //Compute the translation
507   try
508   {
509     if (!GetSolver()->ComputeFunction(aFunction))
510     {
511       SetErrorCode("Healing driver failed");
512       return NULL;
513     }
514   }
515   catch (Standard_Failure)
516   {
517         Handle(Standard_Failure) aFail = Standard_Failure::Caught();
518     SetErrorCode(aFail->GetMessageString());
519     return NULL;
520   }
521
522   //Make a Python command
523   // ...
524   // ... missing ...
525
526   SetErrorCode(OK);
527   return aNewObject;
528 }
529
530 //=============================================================================
531 /*!
532  *  DivideEdge
533  */
534 //=============================================================================
535 Handle(GEOM_Object) GEOMImpl_IHealingOperations::DivideEdge (Handle(GEOM_Object) theObject,
536                                                              int theIndex,
537                                                              double theValue,
538                                                              bool isByParameter)
539 {
540   // set error code, check parameters
541   SetErrorCode(KO);
542
543   if (theObject.IsNull())
544     return NULL;
545
546   Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
547   if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
548
549   // Add a new object
550   Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
551
552   //Add the function
553   aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), DIVIDE_EDGE);
554
555   if (aFunction.IsNull()) return NULL;
556
557   //Check if the function is set correctly
558   if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
559
560   // prepare "data container" class IHealing
561   GEOMImpl_IHealing HI(aFunction);
562   HI.SetIndex( theIndex );
563   HI.SetDevideEdgeValue( theValue );
564   HI.SetIsByParameter( isByParameter );
565   HI.SetOriginal( aLastFunction );
566
567   //Compute the translation
568   try
569   {
570     if (!GetSolver()->ComputeFunction(aFunction))
571     {
572       SetErrorCode("Healing driver failed");
573       return NULL;
574     }
575   }
576   catch (Standard_Failure)
577   {
578         Handle(Standard_Failure) aFail = Standard_Failure::Caught();
579     SetErrorCode(aFail->GetMessageString());
580     return NULL;
581   }
582
583   //Make a Python command
584   // ...
585   // ... missing ...
586
587   SetErrorCode(OK);
588   return aNewObject;
589 }
590
591 //=============================================================================
592 /*!
593  *  GetFreeBoundary
594  */
595 //=============================================================================
596 bool GEOMImpl_IHealingOperations::GetFreeBoundary (Handle(GEOM_Object) theObject,
597                                                    Handle(TColStd_HSequenceOfTransient)& theClosed,
598                                                    Handle(TColStd_HSequenceOfTransient)& theOpen )
599 {
600   // set error code, check parameters
601   SetErrorCode(KO);
602
603   if ( theObject.IsNull() || theClosed.IsNull() || theOpen.IsNull() )
604     return false;
605
606   TopoDS_Shape aShape = theObject->GetValue();
607   if ( aShape.IsNull() )
608     return false;
609
610   // get free boundary shapes
611   ShapeAnalysis_FreeBounds anAnalizer( aShape );
612   TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
613   TopoDS_Compound anOpen = anAnalizer.GetOpenWires();
614
615   // iterate through shapes and append them to the return sequence
616   Handle(GEOM_Object) anObj;
617   Handle(GEOM_Function) aFunction;
618   TopExp_Explorer anExp;
619   for ( anExp.Init( aClosed, TopAbs_WIRE ); anExp.More(); anExp.Next() )
620   {
621     anObj = GetEngine()->AddObject( GetDocID(), GEOM_FREE_BOUNDS );
622     aFunction = anObj->AddFunction( GEOMImpl_CopyDriver::GetID(), COPY_WITHOUT_REF );
623     TopoDS_Shape aValueShape = anExp.Current();
624     aFunction->SetValue( aValueShape );
625     theClosed->Append(anObj);
626   }
627   for ( anExp.Init( anOpen, TopAbs_WIRE ); anExp.More(); anExp.Next() )
628   {
629     anObj = GetEngine()->AddObject( GetDocID(), GEOM_FREE_BOUNDS );
630     aFunction = anObj->AddFunction( GEOMImpl_CopyDriver::GetID(), COPY_WITHOUT_REF );
631     TopoDS_Shape aValueShape = anExp.Current();
632     aFunction->SetValue( aValueShape );
633     theOpen->Append(anObj);
634   }
635
636   SetErrorCode(OK);
637   return true;
638 }