2 #pragma warning( disable:4786 )
5 #include <Standard_Stream.hxx>
7 #include <GEOMImpl_IHealingOperations.hxx>
9 #include <GEOM_PythonDump.hxx>
11 #include <GEOMImpl_HealingDriver.hxx>
12 #include <GEOMImpl_Types.hxx>
13 #include <GEOMImpl_IHealing.hxx>
14 #include <GEOMImpl_CopyDriver.hxx>
16 #include <ShHealOper_ShapeProcess.hxx>
18 #include "utilities.h"
20 #include <Utils_ExceptHandlers.hxx>
22 #include <ShapeAnalysis_FreeBounds.hxx>
24 #include <TopoDS_Compound.hxx>
25 #include <TopExp_Explorer.hxx>
27 #include <TColStd_HArray1OfExtendedString.hxx>
28 #include <TColStd_HSequenceOfTransient.hxx>
29 #include <TCollection_AsciiString.hxx>
31 #include <TDF_Tool.hxx>
33 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
36 //=============================================================================
40 //=============================================================================
42 GEOMImpl_IHealingOperations::GEOMImpl_IHealingOperations (GEOM_Engine* theEngine, int theDocID)
43 : GEOM_IOperations(theEngine, theDocID)
45 MESSAGE("GEOMImpl_IHealingOperations::GEOMImpl_IHealingOperations");
48 //=============================================================================
52 //=============================================================================
54 GEOMImpl_IHealingOperations::~GEOMImpl_IHealingOperations()
56 MESSAGE("GEOMImpl_IHealingOperations::~GEOMImpl_IHealingOperations");
60 //=============================================================================
64 //=============================================================================
65 Handle(GEOM_Object) GEOMImpl_IHealingOperations::ShapeProcess (Handle(GEOM_Object) theObject,
66 const Handle(TColStd_HArray1OfExtendedString)& theOperators,
67 const Handle(TColStd_HArray1OfExtendedString)& theParams,
68 const Handle(TColStd_HArray1OfExtendedString)& theValues)
70 // set error code, check parameters
73 if (theObject.IsNull())
76 if (theOperators.IsNull() || theOperators->Length() <= 0) {
77 SetErrorCode("No operators requested");
81 Standard_Integer nbParams = 0, nbValues = 0;
82 if (!theParams.IsNull()) {
83 nbParams = theParams->Length();
85 if (!theValues.IsNull()) {
86 nbValues = theValues->Length();
89 if (nbParams != nbValues) {
90 SetErrorCode("Number of parameter values must be equal to the number of parameters");
94 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
95 if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
98 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
101 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), SHAPE_PROCESS);
103 if (aFunction.IsNull()) return NULL;
105 //Check if the function is set correctly
106 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
108 // prepare "data container" class IHealing
109 GEOMImpl_IHealing HI(aFunction);
110 HI.SetOriginal(aLastFunction);
111 HI.SetOperators( theOperators );
113 HI.SetParameters( theParams );
114 HI.SetValues( theValues );
117 //Compute the translation
120 if (!GetSolver()->ComputeFunction(aFunction))
122 SetErrorCode("Shape Healing algorithm failed");
126 catch (Standard_Failure)
128 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
129 SetErrorCode(aFail->GetMessageString());
133 //Make a Python command
134 GEOM::TPythonDump pd (aFunction);
135 pd << aNewObject << " = geompy.ProcessShape(" << theObject << ", [";
138 int i = theOperators->Lower(), nb = theOperators->Upper();
139 for ( ; i <= nb; i++) {
140 pd << "\"" << TCollection_AsciiString(theOperators->Value( i )).ToCString()
141 << (( i < nb ) ? "\", " : "\"");
144 // list of parameters
145 i = theParams->Lower(); nb = theParams->Upper();
146 for ( ; i <= nb; i++) {
147 pd << "\"" << TCollection_AsciiString(theParams->Value( i )).ToCString()
148 << (( i < nb ) ? "\", " : "\"");
152 i = theValues->Lower(); nb = theValues->Upper();
153 for ( ; i <= nb; i++) {
154 pd << "\"" << TCollection_AsciiString(theValues->Value( i )).ToCString()
155 << (( i < nb ) ? "\", " : "\"");
163 //=============================================================================
167 //=============================================================================
168 void GEOMImpl_IHealingOperations::GetShapeProcessParameters (list<string>& theOperations,
169 list<string>& theParams,
170 list<string>& theValues)
172 ShHealOper_ShapeProcess aHealer;
173 TColStd_SequenceOfAsciiString anOperators;
174 int nbOperatorErrors( 0 );
175 if ( aHealer.GetOperators( anOperators ) )
177 for ( Standard_Integer i = 1; i <= anOperators.Length(); i++ )
179 string anOperation = anOperators.Value( i ).ToCString();
180 if ( GetOperatorParameters( anOperation, theParams, theValues ) )
181 theOperations.push_back( anOperation );
188 SetErrorCode("ERROR retrieving operators (GEOMImpl_IHealingOperations)");
191 if ( nbOperatorErrors ) {
192 TCollection_AsciiString aMsg ("ERRORS retrieving ShapeProcess parameters (GEOMImpl_IHealingOperations): nbOperatorErrors = ");
193 aMsg += TCollection_AsciiString( nbOperatorErrors );
194 MESSAGE(aMsg.ToCString());
198 //=============================================================================
200 * GetOperatorParameters
202 //=============================================================================
203 bool GEOMImpl_IHealingOperations::GetOperatorParameters( const string theOperation,
204 list<string>& theParams,
205 list<string>& theValues )
207 ShHealOper_ShapeProcess aHealer;
208 int nbParamValueErrors( 0 );
209 list<string> aParams;
210 if ( GetParameters( theOperation, aParams ) ) {
211 for ( list<string>::iterator it = aParams.begin(); it != aParams.end(); ++it ) {
212 TCollection_AsciiString aParam( (Standard_CString)(*it).c_str() );
213 TCollection_AsciiString aValue;
214 if ( aHealer.GetParameter( aParam, aValue ) ) {
215 theParams.push_back( aParam.ToCString() );
216 theValues.push_back( aValue.ToCString() );
219 nbParamValueErrors++;
225 if ( nbParamValueErrors ) {
226 TCollection_AsciiString aMsg ("ERRORS retrieving ShapeProcess parameter values (GEOMImpl_IHealingOperations): nbParamValueErrors = ");
227 aMsg += TCollection_AsciiString( nbParamValueErrors );
228 MESSAGE(aMsg.ToCString());
234 //=============================================================================
238 //=============================================================================
239 bool GEOMImpl_IHealingOperations::GetParameters (const string theOperation,
240 list<string>& theParams)
242 if ( theOperation == "SplitAngle" ) {
243 theParams.push_back( "SplitAngle.Angle" );
244 theParams.push_back( "SplitAngle.MaxTolerance" );
246 } else if ( theOperation == "SplitClosedFaces" ) {
247 theParams.push_back( "SplitClosedFaces.NbSplitPoints" );
249 } else if ( theOperation == "FixFaceSize" ) {
250 theParams.push_back( "FixFaceSize.Tolerance" );
252 } else if( theOperation == "DropSmallEdges" ) {
253 theParams.push_back( "DropSmallEdges.Tolerance3d" );
255 } else if( theOperation == "BSplineRestriction" ) {
256 theParams.push_back( "BSplineRestriction.SurfaceMode" );
257 theParams.push_back( "BSplineRestriction.Curve3dMode" );
258 theParams.push_back( "BSplineRestriction.Curve2dMode" );
259 theParams.push_back( "BSplineRestriction.Tolerance3d" );
260 theParams.push_back( "BSplineRestriction.Tolerance2d" );
261 theParams.push_back( "BSplineRestriction.RequiredDegree" );
262 theParams.push_back( "BSplineRestriction.RequiredNbSegments" );
263 theParams.push_back( "BSplineRestriction.Continuity3d" );
264 theParams.push_back( "BSplineRestriction.Continuity2d" );
266 } else if( theOperation == "SplitContinuity" ) {
267 theParams.push_back( "SplitContinuity.Tolerance3d" );
268 theParams.push_back( "SplitContinuity.SurfaceContinuity" );
269 theParams.push_back( "SplitContinuity.CurveContinuity" );
271 } else if( theOperation == "ToBezier" ) {
272 theParams.push_back( "ToBezier.SurfaceMode" );
273 theParams.push_back( "ToBezier.Curve3dMode" );
274 theParams.push_back( "ToBezier.Curve2dMode" );
275 theParams.push_back( "ToBezier.MaxTolerance" );
277 } else if( theOperation == "SameParameter" ) {
278 theParams.push_back( "SameParameter.Tolerance3d" );
280 } else if( theOperation == "FixShape" ) {
281 theParams.push_back( "FixShape.Tolerance3d" );
282 theParams.push_back( "FixShape.MaxTolerance3d" );
291 //=============================================================================
295 //=============================================================================
296 Handle(GEOM_Object) GEOMImpl_IHealingOperations::SuppressFaces
297 (Handle(GEOM_Object) theObject, const Handle(TColStd_HArray1OfInteger)& theFaces)
299 // set error code, check parameters
302 if ( theObject.IsNull() ) // if theFaces.IsNull() - it's OK, it means that ALL faces must be removed..
305 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
306 if(aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
309 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
312 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), SUPPRESS_FACES);
314 if(aFunction.IsNull()) return NULL;
316 //Check if the function is set correctly
317 if(aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
319 // prepare "data container" class IHealing
320 GEOMImpl_IHealing HI(aFunction);
321 HI.SetFaces( theFaces );
322 HI.SetOriginal( aLastFunction );
324 //Compute the translation
327 if (!GetSolver()->ComputeFunction(aFunction))
329 SetErrorCode("Healing driver failed");
333 catch (Standard_Failure)
335 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
336 SetErrorCode(aFail->GetMessageString());
340 //Make a Python command
341 GEOM::TPythonDump pd (aFunction);
342 pd << aNewObject << " = geompy.SuppressFaces(" << theObject << ", [";
345 int i = theFaces->Lower(), nb = theFaces->Upper();
346 for ( ; i <= nb; i++)
347 pd << theFaces->Value( i ) << (( i < nb ) ? ", " : "])");
354 //=============================================================================
358 //=============================================================================
359 Handle(GEOM_Object) GEOMImpl_IHealingOperations::CloseContour
360 (Handle(GEOM_Object) theObject,
361 const Handle(TColStd_HArray1OfInteger)& theWires,
364 // set error code, check parameters
367 if (theObject.IsNull())
370 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
371 if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
374 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
377 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), CLOSE_CONTOUR);
379 if (aFunction.IsNull()) return NULL;
381 //Check if the function is set correctly
382 if(aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
384 // prepare "data container" class IHealing
385 GEOMImpl_IHealing HI(aFunction);
386 HI.SetWires( theWires );
387 HI.SetIsCommonVertex( isCommonVertex );
388 HI.SetOriginal( aLastFunction );
390 //Compute the translation
393 if (!GetSolver()->ComputeFunction(aFunction))
395 SetErrorCode("Healing driver failed");
399 catch (Standard_Failure)
401 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
402 SetErrorCode(aFail->GetMessageString());
406 //Make a Python command
407 GEOM::TPythonDump pd (aFunction);
408 pd << aNewObject << " = geompy.CloseContour(" << theObject << ", [";
411 int i = theWires->Lower(), nb = theWires->Upper();
412 for ( ; i <= nb; i++)
413 pd << theWires->Value( i ) << (( i < nb ) ? ", " : "], ");
415 pd << (int)isCommonVertex << ")";
421 //=============================================================================
425 //=============================================================================
426 Handle(GEOM_Object) GEOMImpl_IHealingOperations::RemoveIntWires
427 (Handle(GEOM_Object) theObject, const Handle(TColStd_HArray1OfInteger)& theWires)
429 // set error code, check parameters
432 if (theObject.IsNull()) // if theWires is NULL it's OK, it means that ALL wires must be removed
435 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
436 if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
439 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
442 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), REMOVE_INT_WIRES);
444 if (aFunction.IsNull()) return NULL;
446 //Check if the function is set correctly
447 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
449 // prepare "data container" class IHealing
450 GEOMImpl_IHealing HI(aFunction);
451 HI.SetWires( theWires );
452 HI.SetOriginal( aLastFunction );
454 //Compute the translation
457 if (!GetSolver()->ComputeFunction(aFunction))
459 SetErrorCode("Healing driver failed");
463 catch (Standard_Failure)
465 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
466 SetErrorCode(aFail->GetMessageString());
470 //Make a Python command
471 GEOM::TPythonDump pd (aFunction);
472 pd << aNewObject << " = geompy.SuppressInternalWires(" << theObject << ", [";
475 if (!theWires.IsNull()) {
476 int i = theWires->Lower(), nb = theWires->Upper();
477 for ( ; i <= nb; i++)
478 pd << theWires->Value( i ) << (( i < nb ) ? ", " : "])");
487 //=============================================================================
491 //=============================================================================
492 Handle(GEOM_Object) GEOMImpl_IHealingOperations::FillHoles (Handle(GEOM_Object) theObject,
493 const Handle(TColStd_HArray1OfInteger)& theWires)
495 // set error code, check parameters
498 if (theObject.IsNull()) // if theWires is NULL it's OK, it means that ALL holes must be removed
501 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
502 if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
505 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
508 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), FILL_HOLES);
510 if (aFunction.IsNull()) return NULL;
512 //Check if the function is set correctly
513 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
515 // prepare "data container" class IHealing
516 GEOMImpl_IHealing HI(aFunction);
517 HI.SetWires( theWires );
518 HI.SetOriginal( aLastFunction );
520 //Compute the translation
523 if (!GetSolver()->ComputeFunction(aFunction))
525 SetErrorCode("Healing driver failed");
529 catch (Standard_Failure)
531 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
532 SetErrorCode(aFail->GetMessageString());
536 //Make a Python command
537 GEOM::TPythonDump pd (aFunction);
538 pd << aNewObject << " = geompy.SuppressHoles(" << theObject << ", [";
541 if ( theWires.IsNull() )
544 int i = theWires->Lower(), nb = theWires->Upper();
545 for ( ; i <= nb; i++)
546 pd << theWires->Value( i ) << (( i < nb ) ? ", " : "])");
553 //=============================================================================
557 //=============================================================================
558 Handle(GEOM_Object) GEOMImpl_IHealingOperations::Sew (Handle(GEOM_Object) theObject,
561 // set error code, check parameters
564 if (theObject.IsNull())
567 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
568 if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
571 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
574 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), SEWING);
576 if (aFunction.IsNull()) return NULL;
578 //Check if the function is set correctly
579 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
581 // prepare "data container" class IHealing
582 GEOMImpl_IHealing HI(aFunction);
583 HI.SetTolerance( theTolerance );
584 HI.SetOriginal( aLastFunction );
586 //Compute the translation
589 if (!GetSolver()->ComputeFunction(aFunction))
591 SetErrorCode("Healing driver failed");
595 catch (Standard_Failure)
597 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
598 SetErrorCode(aFail->GetMessageString());
602 //Make a Python command
603 GEOM::TPythonDump(aFunction) << aNewObject << " = geompy.Sew("
604 << theObject << ", " << theTolerance << ")";
610 //=============================================================================
614 //=============================================================================
615 Handle(GEOM_Object) GEOMImpl_IHealingOperations::DivideEdge (Handle(GEOM_Object) theObject,
620 // set error code, check parameters
623 if (theObject.IsNull())
626 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
627 if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
630 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
633 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), DIVIDE_EDGE);
635 if (aFunction.IsNull()) return NULL;
637 //Check if the function is set correctly
638 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
640 // prepare "data container" class IHealing
641 GEOMImpl_IHealing HI(aFunction);
642 HI.SetIndex( theIndex );
643 HI.SetDevideEdgeValue( theValue );
644 HI.SetIsByParameter( isByParameter );
645 HI.SetOriginal( aLastFunction );
647 //Compute the translation
650 if (!GetSolver()->ComputeFunction(aFunction))
652 SetErrorCode("Healing driver failed");
656 catch (Standard_Failure)
658 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
659 SetErrorCode(aFail->GetMessageString());
663 //Make a Python command
664 GEOM::TPythonDump(aFunction) << aNewObject << " = geompy.DivideEdge(" << theObject
665 << ", " << theIndex << ", " << theValue << ", " << (int)isByParameter << ")";
671 //=============================================================================
675 //=============================================================================
676 bool GEOMImpl_IHealingOperations::GetFreeBoundary (Handle(GEOM_Object) theObject,
677 Handle(TColStd_HSequenceOfTransient)& theClosed,
678 Handle(TColStd_HSequenceOfTransient)& theOpen )
680 // set error code, check parameters
683 if ( theObject.IsNull() || theClosed.IsNull() || theOpen.IsNull() )
686 TopoDS_Shape aShape = theObject->GetValue();
687 if ( aShape.IsNull() )
690 // get free boundary shapes
691 ShapeAnalysis_FreeBounds anAnalizer( aShape );
692 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
693 TopoDS_Compound anOpen = anAnalizer.GetOpenWires();
695 // iterate through shapes and append them to the return sequence
696 Handle(GEOM_Object) anObj;
697 Handle(GEOM_Function) aFunction;
698 TopExp_Explorer anExp;
699 for ( anExp.Init( aClosed, TopAbs_WIRE ); anExp.More(); anExp.Next() )
701 anObj = GetEngine()->AddObject( GetDocID(), GEOM_FREE_BOUNDS );
702 aFunction = anObj->AddFunction( GEOMImpl_CopyDriver::GetID(), COPY_WITHOUT_REF );
703 TopoDS_Shape aValueShape = anExp.Current();
704 aFunction->SetValue( aValueShape );
705 theClosed->Append(anObj);
707 for ( anExp.Init( anOpen, TopAbs_WIRE ); anExp.More(); anExp.Next() )
709 anObj = GetEngine()->AddObject( GetDocID(), GEOM_FREE_BOUNDS );
710 aFunction = anObj->AddFunction( GEOMImpl_CopyDriver::GetID(), COPY_WITHOUT_REF );
711 TopoDS_Shape aValueShape = anExp.Current();
712 aFunction->SetValue( aValueShape );
713 theOpen->Append(anObj);
716 //Make a Python command
717 GEOM::TPythonDump pd (aFunction);
719 Standard_Integer i, aLen = theClosed->Length();
722 for (i = 1; i <= aLen; i++) {
723 Handle(GEOM_Object) anObj_i = Handle(GEOM_Object)::DownCast(theClosed->Value(i));
724 pd << anObj_i << ((i < aLen) ? ", " : "");
728 pd << "(isDone, empty_list, ";
731 aLen = theOpen->Length();
734 for (i = 1; i <= aLen; i++) {
735 Handle(GEOM_Object) anObj_i = Handle(GEOM_Object)::DownCast(theOpen->Value(i));
736 pd << anObj_i << ((i < aLen) ? ", " : "");
743 pd << ") = geompy.GetFreeBoundary(" << theObject << ")";