Salome HOME
Bug 0020043: EDF 865 GEOM: Object is non valid after translation. Fix object after...
[modules/geom.git] / src / GEOMImpl / GEOMImpl_HealingDriver.cxx
1 // Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
3 // 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either 
7 // version 2.1 of the License.
8 // 
9 // This library is distributed in the hope that it will be useful 
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
12 // Lesser General Public License for more details.
13 //
14 // You should have received a copy of the GNU Lesser General Public  
15 // License along with this library; if not, write to the Free Software 
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 //
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 //
20
21 #include <Standard_Stream.hxx>
22
23 #include <GEOMImpl_HealingDriver.hxx>
24 #include <GEOMImpl_Types.hxx>
25 #include <GEOMImpl_IHealing.hxx>
26 #include <GEOM_Function.hxx>
27
28 #include <ShHealOper_ShapeProcess.hxx>
29 #include <ShHealOper_RemoveFace.hxx>
30 #include <ShHealOper_CloseContour.hxx>
31 #include <ShHealOper_RemoveInternalWires.hxx>
32 #include <ShHealOper_FillHoles.hxx>
33 #include <ShHealOper_Sewing.hxx>
34 #include <ShHealOper_EdgeDivide.hxx>
35 #include <ShHealOper_ChangeOrientation.hxx>
36
37 #include <TopoDS.hxx>
38 #include <TopExp.hxx>
39 #include <TopTools_IndexedMapOfShape.hxx>
40
41 #include <StdFail_NotDone.hxx>
42
43 //=======================================================================
44 //function :  raiseNotDoneExeption
45 //purpose  :  global function: forms error message and raises exeption
46 //=======================================================================
47 void raiseNotDoneExeption( const int theErrorStatus )
48 {
49   switch ( theErrorStatus )
50   {
51   case ShHealOper_NotError:           StdFail_NotDone::Raise( "ShHealOper_NotError_msg" );
52   case ShHealOper_InvalidParameters:  StdFail_NotDone::Raise( "ShHealOper_InvalidParameters_msg" );
53   case ShHealOper_ErrorExecution:
54   default:                            StdFail_NotDone::Raise( "ShHealOper_ErrorExecution_msg" );
55   }
56 }
57
58 //=======================================================================
59 //function : GetID
60 //purpose  :
61 //=======================================================================
62 const Standard_GUID& GEOMImpl_HealingDriver::GetID()
63 {
64   static Standard_GUID aHealingDriver("FF1BBB61-5D14-4df2-980B-3A668264EA16");
65   return aHealingDriver;
66 }
67
68
69 //=======================================================================
70 //function : GEOMImpl_HealingDriver
71 //purpose  :
72 //=======================================================================
73
74 GEOMImpl_HealingDriver::GEOMImpl_HealingDriver()
75 {
76 }
77
78 //=======================================================================
79 //function : Execute
80 //purpose  :
81 //=======================================================================
82 Standard_Integer GEOMImpl_HealingDriver::Execute(TFunction_Logbook& log) const
83 {
84   if (Label().IsNull()) return 0;
85   Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
86
87   if (aFunction.IsNull()) return 0;
88
89   GEOMImpl_IHealing HI (aFunction);
90   Standard_Integer aType = aFunction->GetType();
91   Handle(GEOM_Function) anOriginalFunction = HI.GetOriginal();
92   if (anOriginalFunction.IsNull()) return 0;
93   TopoDS_Shape aShape, anOriginalShape = anOriginalFunction->GetValue();
94   if (anOriginalShape.IsNull()) return 0;
95
96   switch (aType)
97   {
98   case SHAPE_PROCESS:
99     ShapeProcess(&HI, anOriginalShape, aShape);
100     break;
101   case SUPPRESS_FACES:
102     SuppressFaces(&HI, anOriginalShape, aShape);
103     break;
104   case CLOSE_CONTOUR:
105     CloseContour(&HI, anOriginalShape, aShape);
106     break;
107   case REMOVE_INT_WIRES:
108     RemoveIntWires(&HI, anOriginalShape, aShape);
109     break;
110   case FILL_HOLES:
111     RemoveHoles(&HI, anOriginalShape, aShape);
112     break;
113   case SEWING:
114     Sew(&HI, anOriginalShape, aShape);
115     break;
116   case DIVIDE_EDGE:
117     AddPointOnEdge(&HI, anOriginalShape, aShape);
118     break;
119   case CHANGE_ORIENTATION:
120     ChangeOrientation(&HI, anOriginalShape, aShape);
121     break;
122   default:
123     return 0;
124   }
125
126   if (aShape.IsNull())
127     raiseNotDoneExeption( ShHealOper_ErrorExecution );
128
129   aFunction->SetValue(aShape);
130
131   log.SetTouched(Label());
132   return 1;
133 }
134
135 //=======================================================================
136 //function :  ShapeProcess
137 //purpose  :
138 //=======================================================================
139 Standard_Boolean GEOMImpl_HealingDriver::ShapeProcess (GEOMImpl_IHealing* theHI,
140                                                        const TopoDS_Shape& theOriginalShape,
141                                                        TopoDS_Shape& theOutShape) const
142 {
143   Handle(TColStd_HArray1OfExtendedString) anOperators = theHI->GetOperators();
144   Handle(TColStd_HArray1OfExtendedString) aParams = theHI->GetParameters();
145   Handle(TColStd_HArray1OfExtendedString) aValues = theHI->GetValues();
146
147   if (anOperators.IsNull() || anOperators->Length() <= 0)
148     return Standard_False;
149
150   Standard_Integer nbParams = 0, nbValues = 0;
151   if (!aParams.IsNull()) {
152     nbParams = aParams->Length();
153   }
154   if (!aValues.IsNull()) {
155     nbValues = aValues->Length();
156   }
157   if (nbParams != nbValues)
158     return Standard_False;
159
160   ShHealOper_ShapeProcess aHealer;
161   TColStd_SequenceOfAsciiString anOperatorsAS, aParamsAS, aValuesAS;
162   int i;
163   for (i = 1; i <= anOperators->Length(); i++)
164     anOperatorsAS.Append(TCollection_AsciiString(anOperators->Value(i)));
165
166   aHealer.SetOperators(anOperatorsAS);
167
168   for (i = 1; i <= nbParams; i++) {
169     aHealer.SetParameter(TCollection_AsciiString(aParams->Value(i)),
170                          TCollection_AsciiString(aValues->Value(i)));
171   }
172
173   aHealer.Perform(theOriginalShape, theOutShape);
174
175   if (!aHealer.isDone())
176     raiseNotDoneExeption( ShHealOper_NotError );
177
178   return Standard_True;
179 }
180
181 //=======================================================================
182 //function :  SupressFaces
183 //purpose  :
184 //=======================================================================
185 Standard_Boolean GEOMImpl_HealingDriver::SuppressFaces (GEOMImpl_IHealing* theHI,
186                                                         const TopoDS_Shape& theOriginalShape,
187                                                         TopoDS_Shape& theOutShape) const
188 {
189   Handle(TColStd_HArray1OfInteger) aFaces = theHI->GetFaces();
190
191   ShHealOper_RemoveFace aHealer (theOriginalShape);
192
193   Standard_Boolean aResult = Standard_False;
194   if (aFaces.IsNull()) // remove all faces
195   {
196     aResult = aHealer.Perform();
197   } else {
198     TopTools_SequenceOfShape aShapesFaces;
199     TopTools_IndexedMapOfShape aShapes;
200     TopExp::MapShapes(theOriginalShape, aShapes);
201     for (int i = 1; i <= aFaces->Length(); i++) {
202       int indexOfFace = aFaces->Value(i);
203       TopoDS_Shape aFace = aShapes.FindKey(indexOfFace);
204       aShapesFaces.Append(aFace);
205     }
206
207     aResult = aHealer.Perform(aShapesFaces);
208   }
209
210   if ( aResult )
211     theOutShape = aHealer.GetResultShape();
212   else
213     raiseNotDoneExeption( aHealer.GetErrorStatus() );
214
215   return aResult;
216 }
217
218 //=======================================================================
219 //function :  CloseContour
220 //purpose  :
221 //=======================================================================
222 Standard_Boolean GEOMImpl_HealingDriver::CloseContour (GEOMImpl_IHealing* theHI,
223                                                        const TopoDS_Shape& theOriginalShape,
224                                                        TopoDS_Shape& theOutShape) const
225 {
226   Standard_Boolean isByVertex = theHI->GetIsCommonVertex();
227   Handle(TColStd_HArray1OfInteger) aWires = theHI->GetWires();
228
229   ShHealOper_CloseContour aHealer (theOriginalShape);
230
231   Standard_Boolean aResult = Standard_False;
232   if ( aWires.IsNull() ) {
233     if ( theOriginalShape.ShapeType() == TopAbs_WIRE )
234       aResult = aHealer.Perform(TopoDS::Wire(theOriginalShape), isByVertex, !isByVertex);
235   }
236   else {
237     TopTools_SequenceOfShape aShapesWires;
238     TopTools_IndexedMapOfShape aShapes;
239     TopExp::MapShapes(theOriginalShape, aShapes);
240     for (int i = 1; i <= aWires->Length(); i++) {
241       int indexOfWire = aWires->Value(i);
242       TopoDS_Shape aWire = aShapes.FindKey(indexOfWire);
243       aShapesWires.Append(aWire);
244     }
245
246     aResult = aHealer.Perform( aShapesWires, isByVertex, !isByVertex );
247   }
248
249   if (aResult)
250     theOutShape = aHealer.GetResultShape();
251   else
252     raiseNotDoneExeption( aHealer.GetErrorStatus() );
253
254   return aResult;
255 }
256
257 //=======================================================================
258 //function :  RemoveIntWires
259 //purpose  :
260 //=======================================================================
261 Standard_Boolean GEOMImpl_HealingDriver::RemoveIntWires (GEOMImpl_IHealing* theHI,
262                                                          const TopoDS_Shape& theOriginalShape,
263                                                          TopoDS_Shape& theOutShape) const
264 {
265   Handle(TColStd_HArray1OfInteger) aWires = theHI->GetWires();
266
267   ShHealOper_RemoveInternalWires aHealer(theOriginalShape);
268
269   Standard_Boolean aResult = Standard_False;
270   if (aWires.IsNull()) { // remove all faces
271     aResult = aHealer.Remove();
272   } else {
273     TopTools_SequenceOfShape aShapesWires;
274     TopTools_IndexedMapOfShape aShapes;
275     TopExp::MapShapes(theOriginalShape, aShapes);
276     for (int i = 1; i <= aWires->Length(); i++) {
277       int indexOfWire = aWires->Value(i);
278       TopoDS_Shape aWire = aShapes.FindKey(indexOfWire);
279       aShapesWires.Append(aWire);
280     }
281
282     aResult = aHealer.Remove(aShapesWires);
283   }
284
285   if (aResult)
286     theOutShape = aHealer.GetResultShape();
287   else
288     raiseNotDoneExeption( aHealer.GetErrorStatus() );
289
290   return aResult;
291 }
292
293 //=======================================================================
294 //function :  RemoveHoles
295 //purpose  :
296 //=======================================================================
297 Standard_Boolean GEOMImpl_HealingDriver::RemoveHoles (GEOMImpl_IHealing* theHI,
298                                                       const TopoDS_Shape& theOriginalShape,
299                                                       TopoDS_Shape& theOutShape) const
300 {
301   Handle(TColStd_HArray1OfInteger) aWires = theHI->GetWires();
302
303   ShHealOper_FillHoles aHealer (theOriginalShape);
304
305   Standard_Boolean aResult = Standard_False;
306   if (aWires.IsNull()) { // remove all faces
307     aResult = aHealer.Fill();
308   } else {
309     TopTools_SequenceOfShape aShapesWires;
310     TopTools_IndexedMapOfShape aShapes;
311     TopExp::MapShapes(theOriginalShape, aShapes);
312     for (int i = 1; i <= aWires->Length(); i++) {
313       int indexOfWire = aWires->Value(i);
314       TopoDS_Shape aWire = aShapes.FindKey(indexOfWire);
315       aShapesWires.Append(aWire);
316     }
317
318     aResult = aHealer.Fill(aShapesWires);
319   }
320
321   if (aResult)
322     theOutShape = aHealer.GetResultShape();
323   else
324     raiseNotDoneExeption( aHealer.GetErrorStatus() );
325
326   return aResult;
327 }
328
329 //=======================================================================
330 //function :  Sew
331 //purpose  :
332 //=======================================================================
333 Standard_Boolean GEOMImpl_HealingDriver::Sew (GEOMImpl_IHealing* theHI,
334                                               const TopoDS_Shape& theOriginalShape,
335                                               TopoDS_Shape& theOutShape) const
336 {
337   Standard_Real aTol = theHI->GetTolerance();
338
339   ShHealOper_Sewing aHealer (theOriginalShape, aTol);
340
341   Standard_Boolean aResult = aHealer.Perform();
342
343   if (aResult)
344     theOutShape = aHealer.GetResultShape();
345   else
346     raiseNotDoneExeption( aHealer.GetErrorStatus() );
347
348   return aResult;
349 }
350
351 //=======================================================================
352 //function :  AddPointOnEdge
353 //purpose  :
354 //=======================================================================
355 Standard_Boolean GEOMImpl_HealingDriver::AddPointOnEdge (GEOMImpl_IHealing* theHI,
356                                                          const TopoDS_Shape& theOriginalShape,
357                                                          TopoDS_Shape& theOutShape) const
358 {
359   Standard_Boolean isByParameter = theHI->GetIsByParameter();
360   Standard_Integer anIndex = theHI->GetIndex();
361   Standard_Real aValue = theHI->GetDevideEdgeValue();
362
363   ShHealOper_EdgeDivide aHealer (theOriginalShape);
364
365   Standard_Boolean aResult = Standard_False;
366   if (anIndex == -1) { // apply algorythm for the whole shape which is EDGE
367     if (theOriginalShape.ShapeType() == TopAbs_EDGE)
368       aResult = aHealer.Perform(TopoDS::Edge(theOriginalShape), aValue, isByParameter);
369   } else {
370     TopTools_IndexedMapOfShape aShapes;
371     TopExp::MapShapes(theOriginalShape, aShapes);
372     TopoDS_Shape aEdgeShape = aShapes.FindKey(anIndex);
373     if (aEdgeShape.ShapeType() == TopAbs_EDGE)
374       aResult = aHealer.Perform(TopoDS::Edge(aEdgeShape), aValue, isByParameter);
375   }
376
377   if (aResult)
378     theOutShape = aHealer.GetResultShape();
379   else
380     raiseNotDoneExeption( aHealer.GetErrorStatus() );
381
382   return aResult;
383 }
384
385
386 //=======================================================================
387 //function :  ChangeOrientation
388 //purpose  :
389 //=======================================================================
390 Standard_Boolean GEOMImpl_HealingDriver::ChangeOrientation (GEOMImpl_IHealing* theHI,
391                                                             const TopoDS_Shape& theOriginalShape,
392                                                             TopoDS_Shape& theOutShape) const
393 {
394   ShHealOper_ChangeOrientation aHealer (theOriginalShape);
395
396   Standard_Boolean aResult = aHealer.Perform();
397
398   if (aResult)
399     theOutShape = aHealer.GetResultShape();
400   else
401     raiseNotDoneExeption( aHealer.GetErrorStatus() );
402
403   return aResult;
404 }
405
406
407 //=======================================================================
408 //function :  GEOMImpl_HealingDriver_Type_
409 //purpose  :
410 //=======================================================================
411 Standard_EXPORT Handle_Standard_Type& GEOMImpl_HealingDriver_Type_()
412 {
413
414   static Handle_Standard_Type aType1 = STANDARD_TYPE(TFunction_Driver);
415   if ( aType1.IsNull()) aType1 = STANDARD_TYPE(TFunction_Driver);
416   static Handle_Standard_Type aType2 = STANDARD_TYPE(MMgt_TShared);
417   if ( aType2.IsNull()) aType2 = STANDARD_TYPE(MMgt_TShared);
418   static Handle_Standard_Type aType3 = STANDARD_TYPE(Standard_Transient);
419   if ( aType3.IsNull()) aType3 = STANDARD_TYPE(Standard_Transient);
420
421
422   static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,aType3,NULL};
423   static Handle_Standard_Type _aType = new Standard_Type("GEOMImpl_HealingDriver",
424                                                          sizeof(GEOMImpl_HealingDriver),
425                                                          1,
426                                                          (Standard_Address)_Ancestors,
427                                                          (Standard_Address)NULL);
428
429   return _aType;
430 }
431
432 //=======================================================================
433 //function : DownCast
434 //purpose  :
435 //=======================================================================
436
437 const Handle(GEOMImpl_HealingDriver) Handle(GEOMImpl_HealingDriver)::DownCast(const Handle(Standard_Transient)& AnObject)
438 {
439   Handle(GEOMImpl_HealingDriver) _anOtherObject;
440
441   if (!AnObject.IsNull()) {
442      if (AnObject->IsKind(STANDARD_TYPE(GEOMImpl_HealingDriver))) {
443        _anOtherObject = Handle(GEOMImpl_HealingDriver)((Handle(GEOMImpl_HealingDriver)&)AnObject);
444      }
445   }
446
447   return _anOtherObject ;
448 }
449
450