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