1 // Copyright (C) 2007-2010 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
23 #include <Standard_Stream.hxx>
25 #include <GEOMImpl_HealingDriver.hxx>
26 #include <GEOMImpl_Types.hxx>
27 #include <GEOMImpl_IHealing.hxx>
28 #include <GEOM_Function.hxx>
30 #include <GEOMImpl_GlueDriver.hxx>
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>
41 #include <BRep_Builder.hxx>
45 #include <TopoDS_Iterator.hxx>
46 #include <TopTools_IndexedMapOfShape.hxx>
48 #include <Precision.hxx>
50 #include <StdFail_NotDone.hxx>
52 //=======================================================================
53 //function : raiseNotDoneExeption
54 //purpose : global function: forms error message and raises exeption
55 //=======================================================================
56 void raiseNotDoneExeption( const int theErrorStatus )
58 switch ( theErrorStatus )
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" );
67 //=======================================================================
70 //=======================================================================
71 const Standard_GUID& GEOMImpl_HealingDriver::GetID()
73 static Standard_GUID aHealingDriver("FF1BBB61-5D14-4df2-980B-3A668264EA16");
74 return aHealingDriver;
77 //=======================================================================
78 //function : GEOMImpl_HealingDriver
80 //=======================================================================
81 GEOMImpl_HealingDriver::GEOMImpl_HealingDriver()
85 //=======================================================================
88 //=======================================================================
89 Standard_Integer GEOMImpl_HealingDriver::Execute(TFunction_Logbook& log) const
91 if (Label().IsNull()) return 0;
92 Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
94 if (aFunction.IsNull()) return 0;
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;
106 ShapeProcess(&HI, anOriginalShape, aShape);
109 SuppressFaces(&HI, anOriginalShape, aShape);
112 CloseContour(&HI, anOriginalShape, aShape);
114 case REMOVE_INT_WIRES:
115 RemoveIntWires(&HI, anOriginalShape, aShape);
118 RemoveHoles(&HI, anOriginalShape, aShape);
121 Sew(&HI, anOriginalShape, aShape);
124 AddPointOnEdge(&HI, anOriginalShape, aShape);
126 case CHANGE_ORIENTATION:
127 ChangeOrientation(&HI, anOriginalShape, aShape);
134 raiseNotDoneExeption( ShHealOper_ErrorExecution );
136 aFunction->SetValue(aShape);
138 log.SetTouched(Label());
142 //=======================================================================
143 //function : ShapeProcess
145 //=======================================================================
146 Standard_Boolean GEOMImpl_HealingDriver::ShapeProcess (GEOMImpl_IHealing* theHI,
147 const TopoDS_Shape& theOriginalShape,
148 TopoDS_Shape& theOutShape) const
150 Handle(TColStd_HArray1OfExtendedString) anOperators = theHI->GetOperators();
151 Handle(TColStd_HArray1OfExtendedString) aParams = theHI->GetParameters();
152 Handle(TColStd_HArray1OfExtendedString) aValues = theHI->GetValues();
154 if (anOperators.IsNull() || anOperators->Length() <= 0)
155 return Standard_False;
157 Standard_Integer nbParams = 0, nbValues = 0;
158 if (!aParams.IsNull()) {
159 nbParams = aParams->Length();
161 if (!aValues.IsNull()) {
162 nbValues = aValues->Length();
164 if (nbParams != nbValues)
165 return Standard_False;
167 ShHealOper_ShapeProcess aHealer;
168 TColStd_SequenceOfAsciiString anOperatorsAS, aParamsAS, aValuesAS;
170 for (i = 1; i <= anOperators->Length(); i++)
171 anOperatorsAS.Append(TCollection_AsciiString(anOperators->Value(i)));
173 aHealer.SetOperators(anOperatorsAS);
175 for (i = 1; i <= nbParams; i++) {
176 aHealer.SetParameter(TCollection_AsciiString(aParams->Value(i)),
177 TCollection_AsciiString(aValues->Value(i)));
180 aHealer.Perform(theOriginalShape, theOutShape);
182 if (!aHealer.isDone())
183 raiseNotDoneExeption( ShHealOper_NotError );
185 return Standard_True;
188 //=======================================================================
189 //function : SupressFaces
191 //=======================================================================
192 void SuppressFacesRec (const TopTools_SequenceOfShape& theShapesFaces,
193 const TopoDS_Shape& theOriginalShape,
194 TopoDS_Shape& theOutShape)
196 if ((theOriginalShape.ShapeType() != TopAbs_COMPOUND &&
197 theOriginalShape.ShapeType() != TopAbs_COMPSOLID))
199 ShHealOper_RemoveFace aHealer (theOriginalShape);
200 Standard_Boolean aResult = aHealer.Perform(theShapesFaces);
203 theOutShape = aHealer.GetResultShape();
205 raiseNotDoneExeption(aHealer.GetErrorStatus());
213 TopTools_MapOfShape mapShape;
214 TopoDS_Iterator It (theOriginalShape, Standard_True, Standard_True);
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;
228 TopoDS_Shape anOutSh_i;
229 SuppressFacesRec(theShapesFaces, aShape_i, anOutSh_i);
230 if ( !anOutSh_i.IsNull() )
231 BB.Add(CC, anOutSh_i);
235 BB.Add(CC, aShape_i);
243 Standard_Boolean GEOMImpl_HealingDriver::SuppressFaces (GEOMImpl_IHealing* theHI,
244 const TopoDS_Shape& theOriginalShape,
245 TopoDS_Shape& theOutShape) const
247 Handle(TColStd_HArray1OfInteger) aFaces = theHI->GetFaces();
249 Standard_Boolean aResult = Standard_False;
251 if (aFaces.IsNull()) {
252 ShHealOper_RemoveFace aHealer (theOriginalShape);
253 aResult = aHealer.Perform();
256 theOutShape = aHealer.GetResultShape();
258 raiseNotDoneExeption(aHealer.GetErrorStatus());
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);
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);
277 return Standard_True;
280 //=======================================================================
281 //function : CloseContour
283 //=======================================================================
284 Standard_Boolean GEOMImpl_HealingDriver::CloseContour (GEOMImpl_IHealing* theHI,
285 const TopoDS_Shape& theOriginalShape,
286 TopoDS_Shape& theOutShape) const
288 Standard_Boolean isByVertex = theHI->GetIsCommonVertex();
289 Handle(TColStd_HArray1OfInteger) aWires = theHI->GetWires();
291 ShHealOper_CloseContour aHealer (theOriginalShape);
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);
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);
308 aResult = aHealer.Perform( aShapesWires, isByVertex, !isByVertex );
312 theOutShape = aHealer.GetResultShape();
314 raiseNotDoneExeption( aHealer.GetErrorStatus() );
319 //=======================================================================
320 //function : RemoveIntWires
322 //=======================================================================
323 Standard_Boolean GEOMImpl_HealingDriver::RemoveIntWires (GEOMImpl_IHealing* theHI,
324 const TopoDS_Shape& theOriginalShape,
325 TopoDS_Shape& theOutShape) const
327 Handle(TColStd_HArray1OfInteger) aWires = theHI->GetWires();
329 ShHealOper_RemoveInternalWires aHealer(theOriginalShape);
331 Standard_Boolean aResult = Standard_False;
332 if (aWires.IsNull()) { // remove all faces
333 aResult = aHealer.Remove();
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);
344 aResult = aHealer.Remove(aShapesWires);
348 theOutShape = aHealer.GetResultShape();
350 raiseNotDoneExeption( aHealer.GetErrorStatus() );
355 //=======================================================================
356 //function : RemoveHoles
358 //=======================================================================
359 Standard_Boolean GEOMImpl_HealingDriver::RemoveHoles (GEOMImpl_IHealing* theHI,
360 const TopoDS_Shape& theOriginalShape,
361 TopoDS_Shape& theOutShape) const
363 Handle(TColStd_HArray1OfInteger) aWires = theHI->GetWires();
365 ShHealOper_FillHoles aHealer (theOriginalShape);
367 Standard_Boolean aResult = Standard_False;
368 if (aWires.IsNull()) { // remove all faces
369 aResult = aHealer.Fill();
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);
380 aResult = aHealer.Fill(aShapesWires);
384 theOutShape = aHealer.GetResultShape();
386 raiseNotDoneExeption( aHealer.GetErrorStatus() );
391 //=======================================================================
394 //=======================================================================
395 Standard_Boolean GEOMImpl_HealingDriver::Sew (GEOMImpl_IHealing* theHI,
396 const TopoDS_Shape& theOriginalShape,
397 TopoDS_Shape& theOutShape) const
399 Standard_Real aTol = theHI->GetTolerance();
401 ShHealOper_Sewing aHealer (theOriginalShape, aTol);
403 Standard_Boolean aResult = aHealer.Perform();
406 theOutShape = aHealer.GetResultShape();
408 raiseNotDoneExeption( aHealer.GetErrorStatus() );
413 //=======================================================================
414 //function : AddPointOnEdge
416 //=======================================================================
417 Standard_Boolean GEOMImpl_HealingDriver::AddPointOnEdge (GEOMImpl_IHealing* theHI,
418 const TopoDS_Shape& theOriginalShape,
419 TopoDS_Shape& theOutShape) const
421 Standard_Boolean isByParameter = theHI->GetIsByParameter();
422 Standard_Integer anIndex = theHI->GetIndex();
423 Standard_Real aValue = theHI->GetDevideEdgeValue();
425 ShHealOper_EdgeDivide aHealer (theOriginalShape);
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);
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);
440 theOutShape = aHealer.GetResultShape();
442 raiseNotDoneExeption( aHealer.GetErrorStatus() );
448 //=======================================================================
449 //function : ChangeOrientation
451 //=======================================================================
452 Standard_Boolean GEOMImpl_HealingDriver::ChangeOrientation (GEOMImpl_IHealing* theHI,
453 const TopoDS_Shape& theOriginalShape,
454 TopoDS_Shape& theOutShape) const
456 ShHealOper_ChangeOrientation aHealer (theOriginalShape);
458 Standard_Boolean aResult = aHealer.Perform();
461 theOutShape = aHealer.GetResultShape();
463 raiseNotDoneExeption( aHealer.GetErrorStatus() );
469 //=======================================================================
470 //function : GEOMImpl_HealingDriver_Type_
472 //=======================================================================
473 Standard_EXPORT Handle_Standard_Type& GEOMImpl_HealingDriver_Type_()
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);
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),
488 (Standard_Address)_Ancestors,
489 (Standard_Address)NULL);
494 //=======================================================================
495 //function : DownCast
497 //=======================================================================
499 const Handle(GEOMImpl_HealingDriver) Handle(GEOMImpl_HealingDriver)::DownCast(const Handle(Standard_Transient)& AnObject)
501 Handle(GEOMImpl_HealingDriver) _anOtherObject;
503 if (!AnObject.IsNull()) {
504 if (AnObject->IsKind(STANDARD_TYPE(GEOMImpl_HealingDriver))) {
505 _anOtherObject = Handle(GEOMImpl_HealingDriver)((Handle(GEOMImpl_HealingDriver)&)AnObject);
509 return _anOtherObject;