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