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