1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 #include <Standard_Stream.hxx>
24 #include <GEOMImpl_HealingDriver.hxx>
25 #include <GEOMImpl_Types.hxx>
26 #include <GEOMImpl_IHealing.hxx>
27 #include <GEOM_Function.hxx>
29 #include <GEOMImpl_GlueDriver.hxx>
31 #include <ShHealOper_ShapeProcess.hxx>
32 #include <ShHealOper_RemoveFace.hxx>
33 #include <ShHealOper_CloseContour.hxx>
34 #include <ShHealOper_RemoveInternalWires.hxx>
35 #include <ShHealOper_FillHoles.hxx>
36 #include <ShHealOper_Sewing.hxx>
37 #include <ShHealOper_EdgeDivide.hxx>
38 #include <ShHealOper_ChangeOrientation.hxx>
40 #include <BRep_Builder.hxx>
44 #include <TopoDS_Iterator.hxx>
45 #include <TopTools_IndexedMapOfShape.hxx>
47 #include <Precision.hxx>
49 #include <StdFail_NotDone.hxx>
51 //=======================================================================
52 //function : raiseNotDoneExeption
53 //purpose : global function: forms error message and raises exeption
54 //=======================================================================
55 void raiseNotDoneExeption( const int theErrorStatus )
57 switch ( theErrorStatus )
59 case ShHealOper_NotError: StdFail_NotDone::Raise( "ShHealOper_NotError_msg" );
60 case ShHealOper_InvalidParameters: StdFail_NotDone::Raise( "ShHealOper_InvalidParameters_msg" );
61 case ShHealOper_ErrorExecution:
62 default: StdFail_NotDone::Raise( "ShHealOper_ErrorExecution_msg" );
66 //=======================================================================
69 //=======================================================================
70 const Standard_GUID& GEOMImpl_HealingDriver::GetID()
72 static Standard_GUID aHealingDriver("FF1BBB61-5D14-4df2-980B-3A668264EA16");
73 return aHealingDriver;
76 //=======================================================================
77 //function : GEOMImpl_HealingDriver
79 //=======================================================================
80 GEOMImpl_HealingDriver::GEOMImpl_HealingDriver()
84 //=======================================================================
87 //=======================================================================
88 Standard_Integer GEOMImpl_HealingDriver::Execute(TFunction_Logbook& log) const
90 if (Label().IsNull()) return 0;
91 Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
93 if (aFunction.IsNull()) return 0;
95 GEOMImpl_IHealing HI (aFunction);
96 Standard_Integer aType = aFunction->GetType();
97 Handle(GEOM_Function) anOriginalFunction = HI.GetOriginal();
98 if (anOriginalFunction.IsNull()) return 0;
99 TopoDS_Shape aShape, anOriginalShape = anOriginalFunction->GetValue();
100 if (anOriginalShape.IsNull()) return 0;
105 ShapeProcess(&HI, anOriginalShape, aShape);
108 SuppressFaces(&HI, anOriginalShape, aShape);
111 CloseContour(&HI, anOriginalShape, aShape);
113 case REMOVE_INT_WIRES:
114 RemoveIntWires(&HI, anOriginalShape, aShape);
117 RemoveHoles(&HI, anOriginalShape, aShape);
120 Sew(&HI, anOriginalShape, aShape);
123 AddPointOnEdge(&HI, anOriginalShape, aShape);
125 case CHANGE_ORIENTATION:
126 ChangeOrientation(&HI, anOriginalShape, aShape);
133 raiseNotDoneExeption( ShHealOper_ErrorExecution );
135 aFunction->SetValue(aShape);
137 log.SetTouched(Label());
141 //=======================================================================
142 //function : ShapeProcess
144 //=======================================================================
145 Standard_Boolean GEOMImpl_HealingDriver::ShapeProcess (GEOMImpl_IHealing* theHI,
146 const TopoDS_Shape& theOriginalShape,
147 TopoDS_Shape& theOutShape) const
149 Handle(TColStd_HArray1OfExtendedString) anOperators = theHI->GetOperators();
150 Handle(TColStd_HArray1OfExtendedString) aParams = theHI->GetParameters();
151 Handle(TColStd_HArray1OfExtendedString) aValues = theHI->GetValues();
153 if (anOperators.IsNull() || anOperators->Length() <= 0)
154 return Standard_False;
156 Standard_Integer nbParams = 0, nbValues = 0;
157 if (!aParams.IsNull()) {
158 nbParams = aParams->Length();
160 if (!aValues.IsNull()) {
161 nbValues = aValues->Length();
163 if (nbParams != nbValues)
164 return Standard_False;
166 ShHealOper_ShapeProcess aHealer;
167 TColStd_SequenceOfAsciiString anOperatorsAS, aParamsAS, aValuesAS;
169 for (i = 1; i <= anOperators->Length(); i++)
170 anOperatorsAS.Append(TCollection_AsciiString(anOperators->Value(i)));
172 aHealer.SetOperators(anOperatorsAS);
174 for (i = 1; i <= nbParams; i++) {
175 aHealer.SetParameter(TCollection_AsciiString(aParams->Value(i)),
176 TCollection_AsciiString(aValues->Value(i)));
179 aHealer.Perform(theOriginalShape, theOutShape);
181 if (!aHealer.isDone())
182 raiseNotDoneExeption( ShHealOper_NotError );
184 return Standard_True;
187 //=======================================================================
188 //function : SupressFaces
190 //=======================================================================
191 void SuppressFacesRec (const TopTools_SequenceOfShape& theShapesFaces,
192 const TopoDS_Shape& theOriginalShape,
193 TopoDS_Shape& theOutShape)
195 if ((theOriginalShape.ShapeType() != TopAbs_COMPOUND &&
196 theOriginalShape.ShapeType() != TopAbs_COMPSOLID))
198 ShHealOper_RemoveFace aHealer (theOriginalShape);
199 Standard_Boolean aResult = aHealer.Perform(theShapesFaces);
202 theOutShape = aHealer.GetResultShape();
204 raiseNotDoneExeption(aHealer.GetErrorStatus());
212 TopTools_MapOfShape mapShape;
213 TopoDS_Iterator It (theOriginalShape, Standard_True, Standard_True);
215 for (; It.More(); It.Next()) {
216 TopoDS_Shape aShape_i = It.Value();
217 if (mapShape.Add(aShape_i)) {
218 // check, if current shape contains at least one of faces to be removed
219 bool isFound = false;
220 TopTools_IndexedMapOfShape aShapes_i;
221 TopExp::MapShapes(aShape_i, aShapes_i);
222 for (int i = 1; i <= theShapesFaces.Length() && !isFound; i++) {
223 const TopoDS_Shape& aFace_i = theShapesFaces.Value(i);
224 if (aShapes_i.Contains(aFace_i)) isFound = true;
227 TopoDS_Shape anOutSh_i;
228 SuppressFacesRec(theShapesFaces, aShape_i, anOutSh_i);
229 if ( !anOutSh_i.IsNull() )
230 BB.Add(CC, anOutSh_i);
234 BB.Add(CC, aShape_i);
242 Standard_Boolean GEOMImpl_HealingDriver::SuppressFaces (GEOMImpl_IHealing* theHI,
243 const TopoDS_Shape& theOriginalShape,
244 TopoDS_Shape& theOutShape) const
246 Handle(TColStd_HArray1OfInteger) aFaces = theHI->GetFaces();
248 Standard_Boolean aResult = Standard_False;
250 if (aFaces.IsNull()) {
251 ShHealOper_RemoveFace aHealer (theOriginalShape);
252 aResult = aHealer.Perform();
255 theOutShape = aHealer.GetResultShape();
257 raiseNotDoneExeption(aHealer.GetErrorStatus());
260 TopTools_SequenceOfShape aShapesFaces;
261 TopTools_IndexedMapOfShape aShapes;
262 TopExp::MapShapes(theOriginalShape, aShapes);
263 for (int i = 1; i <= aFaces->Length(); i++) {
264 int indexOfFace = aFaces->Value(i);
265 TopoDS_Shape aFace = aShapes.FindKey(indexOfFace);
266 aShapesFaces.Append(aFace);
268 SuppressFacesRec(aShapesFaces, theOriginalShape, theOutShape);
269 if ((theOriginalShape.ShapeType() == TopAbs_COMPOUND ||
270 theOriginalShape.ShapeType() == TopAbs_COMPSOLID)) {
271 TopoDS_Shape aSh = theOutShape;
272 theOutShape = GEOMImpl_GlueDriver::GlueFaces(aSh, Precision::Confusion(), Standard_True);
276 return Standard_True;
279 //=======================================================================
280 //function : CloseContour
282 //=======================================================================
283 Standard_Boolean GEOMImpl_HealingDriver::CloseContour (GEOMImpl_IHealing* theHI,
284 const TopoDS_Shape& theOriginalShape,
285 TopoDS_Shape& theOutShape) const
287 Standard_Boolean isByVertex = theHI->GetIsCommonVertex();
288 Handle(TColStd_HArray1OfInteger) aWires = theHI->GetWires();
290 ShHealOper_CloseContour aHealer (theOriginalShape);
292 Standard_Boolean aResult = Standard_False;
293 if ( aWires.IsNull() ) {
294 if ( theOriginalShape.ShapeType() == TopAbs_WIRE )
295 aResult = aHealer.Perform(TopoDS::Wire(theOriginalShape), isByVertex, !isByVertex);
298 TopTools_SequenceOfShape aShapesWires;
299 TopTools_IndexedMapOfShape aShapes;
300 TopExp::MapShapes(theOriginalShape, aShapes);
301 for (int i = 1; i <= aWires->Length(); i++) {
302 int indexOfWire = aWires->Value(i);
303 TopoDS_Shape aWire = aShapes.FindKey(indexOfWire);
304 aShapesWires.Append(aWire);
307 aResult = aHealer.Perform( aShapesWires, isByVertex, !isByVertex );
311 theOutShape = aHealer.GetResultShape();
313 raiseNotDoneExeption( aHealer.GetErrorStatus() );
318 //=======================================================================
319 //function : RemoveIntWires
321 //=======================================================================
322 Standard_Boolean GEOMImpl_HealingDriver::RemoveIntWires (GEOMImpl_IHealing* theHI,
323 const TopoDS_Shape& theOriginalShape,
324 TopoDS_Shape& theOutShape) const
326 Handle(TColStd_HArray1OfInteger) aWires = theHI->GetWires();
328 ShHealOper_RemoveInternalWires aHealer(theOriginalShape);
330 Standard_Boolean aResult = Standard_False;
331 if (aWires.IsNull()) { // remove all faces
332 aResult = aHealer.Remove();
334 TopTools_SequenceOfShape aShapesWires;
335 TopTools_IndexedMapOfShape aShapes;
336 TopExp::MapShapes(theOriginalShape, aShapes);
337 for (int i = 1; i <= aWires->Length(); i++) {
338 int indexOfWire = aWires->Value(i);
339 TopoDS_Shape aWire = aShapes.FindKey(indexOfWire);
340 aShapesWires.Append(aWire);
343 aResult = aHealer.Remove(aShapesWires);
347 theOutShape = aHealer.GetResultShape();
349 raiseNotDoneExeption( aHealer.GetErrorStatus() );
354 //=======================================================================
355 //function : RemoveHoles
357 //=======================================================================
358 Standard_Boolean GEOMImpl_HealingDriver::RemoveHoles (GEOMImpl_IHealing* theHI,
359 const TopoDS_Shape& theOriginalShape,
360 TopoDS_Shape& theOutShape) const
362 Handle(TColStd_HArray1OfInteger) aWires = theHI->GetWires();
364 ShHealOper_FillHoles aHealer (theOriginalShape);
366 Standard_Boolean aResult = Standard_False;
367 if (aWires.IsNull()) { // remove all faces
368 aResult = aHealer.Fill();
370 TopTools_SequenceOfShape aShapesWires;
371 TopTools_IndexedMapOfShape aShapes;
372 TopExp::MapShapes(theOriginalShape, aShapes);
373 for (int i = 1; i <= aWires->Length(); i++) {
374 int indexOfWire = aWires->Value(i);
375 TopoDS_Shape aWire = aShapes.FindKey(indexOfWire);
376 aShapesWires.Append(aWire);
379 aResult = aHealer.Fill(aShapesWires);
383 theOutShape = aHealer.GetResultShape();
385 raiseNotDoneExeption( aHealer.GetErrorStatus() );
390 //=======================================================================
393 //=======================================================================
394 Standard_Boolean GEOMImpl_HealingDriver::Sew (GEOMImpl_IHealing* theHI,
395 const TopoDS_Shape& theOriginalShape,
396 TopoDS_Shape& theOutShape) const
398 Standard_Real aTol = theHI->GetTolerance();
400 ShHealOper_Sewing aHealer (theOriginalShape, aTol);
402 Standard_Boolean aResult = aHealer.Perform();
405 theOutShape = aHealer.GetResultShape();
407 raiseNotDoneExeption( aHealer.GetErrorStatus() );
412 //=======================================================================
413 //function : AddPointOnEdge
415 //=======================================================================
416 Standard_Boolean GEOMImpl_HealingDriver::AddPointOnEdge (GEOMImpl_IHealing* theHI,
417 const TopoDS_Shape& theOriginalShape,
418 TopoDS_Shape& theOutShape) const
420 Standard_Boolean isByParameter = theHI->GetIsByParameter();
421 Standard_Integer anIndex = theHI->GetIndex();
422 Standard_Real aValue = theHI->GetDevideEdgeValue();
424 ShHealOper_EdgeDivide aHealer (theOriginalShape);
426 Standard_Boolean aResult = Standard_False;
427 if (anIndex == -1) { // apply algorythm for the whole shape which is EDGE
428 if (theOriginalShape.ShapeType() == TopAbs_EDGE)
429 aResult = aHealer.Perform(TopoDS::Edge(theOriginalShape), aValue, isByParameter);
431 TopTools_IndexedMapOfShape aShapes;
432 TopExp::MapShapes(theOriginalShape, aShapes);
433 TopoDS_Shape aEdgeShape = aShapes.FindKey(anIndex);
434 if (aEdgeShape.ShapeType() == TopAbs_EDGE)
435 aResult = aHealer.Perform(TopoDS::Edge(aEdgeShape), aValue, isByParameter);
439 theOutShape = aHealer.GetResultShape();
441 raiseNotDoneExeption( aHealer.GetErrorStatus() );
447 //=======================================================================
448 //function : ChangeOrientation
450 //=======================================================================
451 Standard_Boolean GEOMImpl_HealingDriver::ChangeOrientation (GEOMImpl_IHealing* theHI,
452 const TopoDS_Shape& theOriginalShape,
453 TopoDS_Shape& theOutShape) const
455 ShHealOper_ChangeOrientation aHealer (theOriginalShape);
457 Standard_Boolean aResult = aHealer.Perform();
460 theOutShape = aHealer.GetResultShape();
462 raiseNotDoneExeption( aHealer.GetErrorStatus() );
468 //=======================================================================
469 //function : GEOMImpl_HealingDriver_Type_
471 //=======================================================================
472 Standard_EXPORT Handle_Standard_Type& GEOMImpl_HealingDriver_Type_()
475 static Handle_Standard_Type aType1 = STANDARD_TYPE(TFunction_Driver);
476 if ( aType1.IsNull()) aType1 = STANDARD_TYPE(TFunction_Driver);
477 static Handle_Standard_Type aType2 = STANDARD_TYPE(MMgt_TShared);
478 if ( aType2.IsNull()) aType2 = STANDARD_TYPE(MMgt_TShared);
479 static Handle_Standard_Type aType3 = STANDARD_TYPE(Standard_Transient);
480 if ( aType3.IsNull()) aType3 = STANDARD_TYPE(Standard_Transient);
483 static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,aType3,NULL};
484 static Handle_Standard_Type _aType = new Standard_Type("GEOMImpl_HealingDriver",
485 sizeof(GEOMImpl_HealingDriver),
487 (Standard_Address)_Ancestors,
488 (Standard_Address)NULL);
493 //=======================================================================
494 //function : DownCast
496 //=======================================================================
498 const Handle(GEOMImpl_HealingDriver) Handle(GEOMImpl_HealingDriver)::DownCast(const Handle(Standard_Transient)& AnObject)
500 Handle(GEOMImpl_HealingDriver) _anOtherObject;
502 if (!AnObject.IsNull()) {
503 if (AnObject->IsKind(STANDARD_TYPE(GEOMImpl_HealingDriver))) {
504 _anOtherObject = Handle(GEOMImpl_HealingDriver)((Handle(GEOMImpl_HealingDriver)&)AnObject);
508 return _anOtherObject;