3 #include "GEOMImpl_IHealingOperations.hxx"
5 #include "GEOM_PythonDump.hxx"
7 #include "GEOMImpl_HealingDriver.hxx"
8 #include "GEOMImpl_Types.hxx"
9 #include "GEOMImpl_IHealing.hxx"
10 #include "GEOMImpl_CopyDriver.hxx"
12 #include "ShHealOper_ShapeProcess.hxx"
14 #include "utilities.h"
16 #include "Utils_ExceptHandlers.hxx"
18 #include <ShapeAnalysis_FreeBounds.hxx>
20 #include <TopoDS_Compound.hxx>
21 #include <TopExp_Explorer.hxx>
23 #include <TColStd_HArray1OfExtendedString.hxx>
24 #include <TColStd_HSequenceOfTransient.hxx>
25 #include <TCollection_AsciiString.hxx>
27 #include <TDF_Tool.hxx>
29 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
32 //=============================================================================
36 //=============================================================================
38 GEOMImpl_IHealingOperations::GEOMImpl_IHealingOperations (GEOM_Engine* theEngine, int theDocID)
39 : GEOM_IOperations(theEngine, theDocID)
41 MESSAGE("GEOMImpl_IHealingOperations::GEOMImpl_IHealingOperations");
44 //=============================================================================
48 //=============================================================================
50 GEOMImpl_IHealingOperations::~GEOMImpl_IHealingOperations()
52 MESSAGE("GEOMImpl_IHealingOperations::~GEOMImpl_IHealingOperations");
56 //=============================================================================
60 //=============================================================================
61 Handle(GEOM_Object) GEOMImpl_IHealingOperations::ShapeProcess (Handle(GEOM_Object) theObject,
62 const Handle(TColStd_HArray1OfExtendedString)& theOperators,
63 const Handle(TColStd_HArray1OfExtendedString)& theParams,
64 const Handle(TColStd_HArray1OfExtendedString)& theValues)
66 // set error code, check parameters
69 if (theObject.IsNull())
72 if (theOperators.IsNull() || theOperators->Length() <= 0) {
73 SetErrorCode("No operators requested");
77 Standard_Integer nbParams = 0, nbValues = 0;
78 if (!theParams.IsNull()) {
79 nbParams = theParams->Length();
81 if (!theValues.IsNull()) {
82 nbValues = theValues->Length();
85 if (nbParams != nbValues) {
86 SetErrorCode("Number of parameter values must be equal to the number of parameters");
90 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
91 if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
94 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
97 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), SHAPE_PROCESS);
99 if (aFunction.IsNull()) return NULL;
101 //Check if the function is set correctly
102 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
104 // prepare "data container" class IHealing
105 GEOMImpl_IHealing HI(aFunction);
106 HI.SetOriginal(aLastFunction);
107 HI.SetOperators( theOperators );
109 HI.SetParameters( theParams );
110 HI.SetValues( theValues );
113 //Compute the translation
116 if (!GetSolver()->ComputeFunction(aFunction))
118 SetErrorCode("Shape Healing algorithm failed");
122 catch (Standard_Failure)
124 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
125 SetErrorCode(aFail->GetMessageString());
129 //Make a Python command
130 GEOM::TPythonDump pd (aFunction);
131 pd << aNewObject << " = geompy.ProcessShape(" << theObject << ", [";
134 int i = theOperators->Lower(), nb = theOperators->Upper();
135 for ( ; i <= nb; i++) {
136 pd << "\"" << TCollection_AsciiString(theOperators->Value( i )).ToCString()
137 << (( i < nb ) ? "\", " : "\"");
140 // list of parameters
141 i = theParams->Lower(); nb = theParams->Upper();
142 for ( ; i <= nb; i++) {
143 pd << "\"" << TCollection_AsciiString(theParams->Value( i )).ToCString()
144 << (( i < nb ) ? "\", " : "\"");
148 i = theValues->Lower(); nb = theValues->Upper();
149 for ( ; i <= nb; i++) {
150 pd << "\"" << TCollection_AsciiString(theValues->Value( i )).ToCString()
151 << (( i < nb ) ? "\", " : "\"");
159 //=============================================================================
163 //=============================================================================
164 void GEOMImpl_IHealingOperations::GetShapeProcessParameters (list<string>& theOperations,
165 list<string>& theParams,
166 list<string>& theValues)
168 ShHealOper_ShapeProcess aHealer;
169 TColStd_SequenceOfAsciiString anOperators;
170 int nbOperatorErrors( 0 );
171 if ( aHealer.GetOperators( anOperators ) )
173 for ( Standard_Integer i = 1; i <= anOperators.Length(); i++ )
175 string anOperation = anOperators.Value( i ).ToCString();
176 if ( GetOperatorParameters( anOperation, theParams, theValues ) )
177 theOperations.push_back( anOperation );
184 SetErrorCode("ERROR retrieving operators (GEOMImpl_IHealingOperations)");
187 if ( nbOperatorErrors ) {
188 TCollection_AsciiString aMsg ("ERRORS retrieving ShapeProcess parameters (GEOMImpl_IHealingOperations): nbOperatorErrors = ");
189 aMsg += TCollection_AsciiString( nbOperatorErrors );
190 MESSAGE(aMsg.ToCString());
194 //=============================================================================
196 * GetOperatorParameters
198 //=============================================================================
199 bool GEOMImpl_IHealingOperations::GetOperatorParameters( const string theOperation,
200 list<string>& theParams,
201 list<string>& theValues )
203 ShHealOper_ShapeProcess aHealer;
204 int nbParamValueErrors( 0 );
205 list<string> aParams;
206 if ( GetParameters( theOperation, aParams ) ) {
207 for ( list<string>::iterator it = aParams.begin(); it != aParams.end(); ++it ) {
208 TCollection_AsciiString aParam( (Standard_CString)(*it).c_str() );
209 TCollection_AsciiString aValue;
210 if ( aHealer.GetParameter( aParam, aValue ) ) {
211 theParams.push_back( aParam.ToCString() );
212 theValues.push_back( aValue.ToCString() );
215 nbParamValueErrors++;
221 if ( nbParamValueErrors ) {
222 TCollection_AsciiString aMsg ("ERRORS retrieving ShapeProcess parameter values (GEOMImpl_IHealingOperations): nbParamValueErrors = ");
223 aMsg += TCollection_AsciiString( nbParamValueErrors );
224 MESSAGE(aMsg.ToCString());
230 //=============================================================================
234 //=============================================================================
235 bool GEOMImpl_IHealingOperations::GetParameters (const string theOperation,
236 list<string>& theParams)
238 if ( theOperation == "SplitAngle" ) {
239 theParams.push_back( "SplitAngle.Angle" );
240 theParams.push_back( "SplitAngle.MaxTolerance" );
242 } else if ( theOperation == "SplitClosedFaces" ) {
243 theParams.push_back( "SplitClosedFaces.NbSplitPoints" );
245 } else if ( theOperation == "FixFaceSize" ) {
246 theParams.push_back( "FixFaceSize.Tolerance" );
248 } else if( theOperation == "DropSmallEdges" ) {
249 theParams.push_back( "DropSmallEdges.Tolerance3d" );
251 } else if( theOperation == "BSplineRestriction" ) {
252 theParams.push_back( "BSplineRestriction.SurfaceMode" );
253 theParams.push_back( "BSplineRestriction.Curve3dMode" );
254 theParams.push_back( "BSplineRestriction.Curve2dMode" );
255 theParams.push_back( "BSplineRestriction.Tolerance3d" );
256 theParams.push_back( "BSplineRestriction.Tolerance2d" );
257 theParams.push_back( "BSplineRestriction.RequiredDegree" );
258 theParams.push_back( "BSplineRestriction.RequiredNbSegments" );
259 theParams.push_back( "BSplineRestriction.Continuity3d" );
260 theParams.push_back( "BSplineRestriction.Continuity2d" );
262 } else if( theOperation == "SplitContinuity" ) {
263 theParams.push_back( "SplitContinuity.Tolerance3d" );
264 theParams.push_back( "SplitContinuity.SurfaceContinuity" );
265 theParams.push_back( "SplitContinuity.CurveContinuity" );
267 } else if( theOperation == "ToBezier" ) {
268 theParams.push_back( "ToBezier.SurfaceMode" );
269 theParams.push_back( "ToBezier.Curve3dMode" );
270 theParams.push_back( "ToBezier.Curve2dMode" );
271 theParams.push_back( "ToBezier.MaxTolerance" );
273 } else if( theOperation == "SameParameter" ) {
274 theParams.push_back( "SameParameter.Tolerance3d" );
276 } else if( theOperation == "FixShape" ) {
277 theParams.push_back( "FixShape.Tolerance3d" );
278 theParams.push_back( "FixShape.MaxTolerance3d" );
287 //=============================================================================
291 //=============================================================================
292 Handle(GEOM_Object) GEOMImpl_IHealingOperations::SuppressFaces
293 (Handle(GEOM_Object) theObject, const Handle(TColStd_HArray1OfInteger)& theFaces)
295 // set error code, check parameters
298 if ( theObject.IsNull() ) // if theFaces.IsNull() - it's OK, it means that ALL faces must be removed..
301 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
302 if(aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
305 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
308 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), SUPPRESS_FACES);
310 if(aFunction.IsNull()) return NULL;
312 //Check if the function is set correctly
313 if(aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
315 // prepare "data container" class IHealing
316 GEOMImpl_IHealing HI(aFunction);
317 HI.SetFaces( theFaces );
318 HI.SetOriginal( aLastFunction );
320 //Compute the translation
323 if (!GetSolver()->ComputeFunction(aFunction))
325 SetErrorCode("Healing driver failed");
329 catch (Standard_Failure)
331 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
332 SetErrorCode(aFail->GetMessageString());
336 //Make a Python command
337 GEOM::TPythonDump pd (aFunction);
338 pd << aNewObject << " = geompy.SuppressFaces(" << theObject << ", [";
341 int i = theFaces->Lower(), nb = theFaces->Upper();
342 for ( ; i <= nb; i++)
343 pd << theFaces->Value( i ) << (( i < nb ) ? ", " : "])");
350 //=============================================================================
354 //=============================================================================
355 Handle(GEOM_Object) GEOMImpl_IHealingOperations::CloseContour
356 (Handle(GEOM_Object) theObject,
357 const Handle(TColStd_HArray1OfInteger)& theWires,
360 // set error code, check parameters
363 if (theObject.IsNull())
366 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
367 if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
370 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
373 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), CLOSE_CONTOUR);
375 if (aFunction.IsNull()) return NULL;
377 //Check if the function is set correctly
378 if(aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
380 // prepare "data container" class IHealing
381 GEOMImpl_IHealing HI(aFunction);
382 HI.SetWires( theWires );
383 HI.SetIsCommonVertex( isCommonVertex );
384 HI.SetOriginal( aLastFunction );
386 //Compute the translation
389 if (!GetSolver()->ComputeFunction(aFunction))
391 SetErrorCode("Healing driver failed");
395 catch (Standard_Failure)
397 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
398 SetErrorCode(aFail->GetMessageString());
402 //Make a Python command
403 GEOM::TPythonDump pd (aFunction);
404 pd << aNewObject << " = geompy.CloseContour(" << theObject << ", [";
407 int i = theWires->Lower(), nb = theWires->Upper();
408 for ( ; i <= nb; i++)
409 pd << theWires->Value( i ) << (( i < nb ) ? ", " : "], ");
411 pd << (int)isCommonVertex << ")";
417 //=============================================================================
421 //=============================================================================
422 Handle(GEOM_Object) GEOMImpl_IHealingOperations::RemoveIntWires
423 (Handle(GEOM_Object) theObject, const Handle(TColStd_HArray1OfInteger)& theWires)
425 // set error code, check parameters
428 if (theObject.IsNull()) // if theWires is NULL it's OK, it means that ALL wires must be removed
431 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
432 if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
435 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
438 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), REMOVE_INT_WIRES);
440 if (aFunction.IsNull()) return NULL;
442 //Check if the function is set correctly
443 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
445 // prepare "data container" class IHealing
446 GEOMImpl_IHealing HI(aFunction);
447 HI.SetWires( theWires );
448 HI.SetOriginal( aLastFunction );
450 //Compute the translation
453 if (!GetSolver()->ComputeFunction(aFunction))
455 SetErrorCode("Healing driver failed");
459 catch (Standard_Failure)
461 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
462 SetErrorCode(aFail->GetMessageString());
466 //Make a Python command
467 GEOM::TPythonDump pd (aFunction);
468 pd << aNewObject << " = geompy.SuppressInternalWires(" << theObject << ", [";
471 if (!theWires.IsNull()) {
472 int i = theWires->Lower(), nb = theWires->Upper();
473 for ( ; i <= nb; i++)
474 pd << theWires->Value( i ) << (( i < nb ) ? ", " : "])");
483 //=============================================================================
487 //=============================================================================
488 Handle(GEOM_Object) GEOMImpl_IHealingOperations::FillHoles (Handle(GEOM_Object) theObject,
489 const Handle(TColStd_HArray1OfInteger)& theWires)
491 // set error code, check parameters
494 if (theObject.IsNull()) // if theWires is NULL it's OK, it means that ALL holes must be removed
497 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
498 if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
501 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
504 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), FILL_HOLES);
506 if (aFunction.IsNull()) return NULL;
508 //Check if the function is set correctly
509 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
511 // prepare "data container" class IHealing
512 GEOMImpl_IHealing HI(aFunction);
513 HI.SetWires( theWires );
514 HI.SetOriginal( aLastFunction );
516 //Compute the translation
519 if (!GetSolver()->ComputeFunction(aFunction))
521 SetErrorCode("Healing driver failed");
525 catch (Standard_Failure)
527 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
528 SetErrorCode(aFail->GetMessageString());
532 //Make a Python command
533 GEOM::TPythonDump pd (aFunction);
534 pd << aNewObject << " = geompy.SuppressHoles(" << theObject << ", [";
537 int i = theWires->Lower(), nb = theWires->Upper();
538 for ( ; i <= nb; i++)
539 pd << theWires->Value( i ) << (( i < nb ) ? ", " : "])");
545 //=============================================================================
549 //=============================================================================
550 Handle(GEOM_Object) GEOMImpl_IHealingOperations::Sew (Handle(GEOM_Object) theObject,
553 // set error code, check parameters
556 if (theObject.IsNull())
559 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
560 if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
563 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
566 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), SEWING);
568 if (aFunction.IsNull()) return NULL;
570 //Check if the function is set correctly
571 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
573 // prepare "data container" class IHealing
574 GEOMImpl_IHealing HI(aFunction);
575 HI.SetTolerance( theTolerance );
576 HI.SetOriginal( aLastFunction );
578 //Compute the translation
581 if (!GetSolver()->ComputeFunction(aFunction))
583 SetErrorCode("Healing driver failed");
587 catch (Standard_Failure)
589 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
590 SetErrorCode(aFail->GetMessageString());
594 //Make a Python command
595 GEOM::TPythonDump(aFunction) << aNewObject << " = geompy.Sew("
596 << theObject << ", " << theTolerance << ")";
602 //=============================================================================
606 //=============================================================================
607 Handle(GEOM_Object) GEOMImpl_IHealingOperations::DivideEdge (Handle(GEOM_Object) theObject,
612 // set error code, check parameters
615 if (theObject.IsNull())
618 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
619 if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
622 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
625 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), DIVIDE_EDGE);
627 if (aFunction.IsNull()) return NULL;
629 //Check if the function is set correctly
630 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
632 // prepare "data container" class IHealing
633 GEOMImpl_IHealing HI(aFunction);
634 HI.SetIndex( theIndex );
635 HI.SetDevideEdgeValue( theValue );
636 HI.SetIsByParameter( isByParameter );
637 HI.SetOriginal( aLastFunction );
639 //Compute the translation
642 if (!GetSolver()->ComputeFunction(aFunction))
644 SetErrorCode("Healing driver failed");
648 catch (Standard_Failure)
650 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
651 SetErrorCode(aFail->GetMessageString());
655 //Make a Python command
656 GEOM::TPythonDump(aFunction) << aNewObject << " = geompy.DivideEdge(" << theObject
657 << ", " << theIndex << ", " << theValue << ", " << (int)isByParameter << ")";
663 //=============================================================================
667 //=============================================================================
668 bool GEOMImpl_IHealingOperations::GetFreeBoundary (Handle(GEOM_Object) theObject,
669 Handle(TColStd_HSequenceOfTransient)& theClosed,
670 Handle(TColStd_HSequenceOfTransient)& theOpen )
672 // set error code, check parameters
675 if ( theObject.IsNull() || theClosed.IsNull() || theOpen.IsNull() )
678 TopoDS_Shape aShape = theObject->GetValue();
679 if ( aShape.IsNull() )
682 // get free boundary shapes
683 ShapeAnalysis_FreeBounds anAnalizer( aShape );
684 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
685 TopoDS_Compound anOpen = anAnalizer.GetOpenWires();
687 // iterate through shapes and append them to the return sequence
688 Handle(GEOM_Object) anObj;
689 Handle(GEOM_Function) aFunction;
690 TopExp_Explorer anExp;
691 for ( anExp.Init( aClosed, TopAbs_WIRE ); anExp.More(); anExp.Next() )
693 anObj = GetEngine()->AddObject( GetDocID(), GEOM_FREE_BOUNDS );
694 aFunction = anObj->AddFunction( GEOMImpl_CopyDriver::GetID(), COPY_WITHOUT_REF );
695 TopoDS_Shape aValueShape = anExp.Current();
696 aFunction->SetValue( aValueShape );
697 theClosed->Append(anObj);
699 for ( anExp.Init( anOpen, 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 theOpen->Append(anObj);
708 //Make a Python command
709 GEOM::TPythonDump pd (aFunction);
711 Standard_Integer i, aLen = theClosed->Length();
714 for (i = 1; i <= aLen; i++) {
715 Handle(GEOM_Object) anObj_i = Handle(GEOM_Object)::DownCast(theClosed->Value(i));
716 pd << anObj_i << ((i < aLen) ? ", " : "");
720 pd << "(isDone, empty_list, ";
723 aLen = theOpen->Length();
726 for (i = 1; i <= aLen; i++) {
727 Handle(GEOM_Object) anObj_i = Handle(GEOM_Object)::DownCast(theOpen->Value(i));
728 pd << anObj_i << ((i < aLen) ? ", " : "");
735 pd << ") = geompy.GetFreeBoundary(" << theObject << ")";