1 // Copyright (C) 2007-2014 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, or (at your option) any later version.
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
24 #pragma warning( disable:4786 )
27 #include <Standard_Version.hxx>
28 #include <Standard_Stream.hxx>
30 #include <GEOMImpl_IHealingOperations.hxx>
32 #include <GEOM_PythonDump.hxx>
34 #include <GEOMImpl_HealingDriver.hxx>
35 #include <GEOMImpl_Types.hxx>
36 #include <GEOMImpl_IHealing.hxx>
37 #include <GEOMImpl_IVector.hxx>
38 #include <GEOMImpl_VectorDriver.hxx>
39 #include <GEOMImpl_CopyDriver.hxx>
41 #include <Basics_OCCTVersion.hxx>
43 #include "utilities.h"
45 #include <Utils_ExceptHandlers.hxx>
47 #include <ShHealOper_ShapeProcess.hxx>
49 #include <ShapeAnalysis_FreeBounds.hxx>
51 #include <TopoDS_Compound.hxx>
52 #include <TopExp_Explorer.hxx>
54 #include <TColStd_HArray1OfExtendedString.hxx>
55 #include <TColStd_HSequenceOfTransient.hxx>
56 #include <TCollection_AsciiString.hxx>
58 #include <TDF_Tool.hxx>
60 #include <Standard_Failure.hxx>
61 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
63 //=============================================================================
67 //=============================================================================
68 GEOMImpl_IHealingOperations::GEOMImpl_IHealingOperations (GEOM_Engine* theEngine, int theDocID)
69 : GEOM_IOperations(theEngine, theDocID)
71 MESSAGE("GEOMImpl_IHealingOperations::GEOMImpl_IHealingOperations");
74 //=============================================================================
78 //=============================================================================
79 GEOMImpl_IHealingOperations::~GEOMImpl_IHealingOperations()
81 MESSAGE("GEOMImpl_IHealingOperations::~GEOMImpl_IHealingOperations");
85 //=============================================================================
89 //=============================================================================
90 Handle(GEOM_Object) GEOMImpl_IHealingOperations::ShapeProcess (Handle(GEOM_Object) theObject,
91 const Handle(TColStd_HArray1OfExtendedString)& theOperators,
92 const Handle(TColStd_HArray1OfExtendedString)& theParams,
93 const Handle(TColStd_HArray1OfExtendedString)& theValues)
95 // set error code, check parameters
98 if (theObject.IsNull())
101 if (theOperators.IsNull() || theOperators->Length() <= 0) {
102 SetErrorCode("No operators requested");
106 Standard_Integer nbParams = 0, nbValues = 0;
107 if (!theParams.IsNull()) {
108 nbParams = theParams->Length();
110 if (!theValues.IsNull()) {
111 nbValues = theValues->Length();
114 if (nbParams != nbValues) {
115 SetErrorCode("Number of parameter values must be equal to the number of parameters");
119 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
120 if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
123 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
126 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), SHAPE_PROCESS);
128 if (aFunction.IsNull()) return NULL;
130 //Check if the function is set correctly
131 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
133 // prepare "data container" class IHealing
134 GEOMImpl_IHealing HI(aFunction);
135 HI.SetOriginal(aLastFunction);
136 HI.SetOperators( theOperators );
138 HI.SetParameters( theParams );
139 HI.SetValues( theValues );
142 //Compute the translation
145 if (!GetSolver()->ComputeFunction(aFunction))
147 SetErrorCode("Shape Healing algorithm failed");
151 catch (Standard_Failure)
153 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
154 SetErrorCode(aFail->GetMessageString());
158 //Make a Python command
159 GEOM::TPythonDump pd (aFunction);
160 pd << aNewObject << " = geompy.ProcessShape(" << theObject << ", [";
163 int i = theOperators->Lower(), nb = theOperators->Upper();
164 for ( ; i <= nb; i++) {
165 pd << "\"" << TCollection_AsciiString(theOperators->Value( i )).ToCString()
166 << (( i < nb ) ? "\", " : "\"");
169 // list of parameters
170 i = theParams->Lower(); nb = theParams->Upper();
171 for ( ; i <= nb; i++) {
172 pd << "\"" << TCollection_AsciiString(theParams->Value( i )).ToCString()
173 << (( i < nb ) ? "\", " : "\"");
177 i = theValues->Lower(); nb = theValues->Upper();
178 for ( ; i <= nb; i++) {
179 pd << "\"" << TCollection_AsciiString(theValues->Value( i )).ToCString()
180 << (( i < nb ) ? "\", " : "\"");
188 //=============================================================================
192 //=============================================================================
193 void GEOMImpl_IHealingOperations::GetShapeProcessParameters (std::list<std::string>& theOperations,
194 std::list<std::string>& theParams,
195 std::list<std::string>& theValues)
197 ShHealOper_ShapeProcess aHealer;
198 TColStd_SequenceOfAsciiString anOperators;
199 int nbOperatorErrors( 0 );
200 if ( aHealer.GetOperators( anOperators ) )
202 for ( Standard_Integer i = 1; i <= anOperators.Length(); i++ )
204 std::string anOperation = anOperators.Value( i ).ToCString();
205 if ( GetOperatorParameters( anOperation, theParams, theValues ) )
206 theOperations.push_back( anOperation );
213 SetErrorCode("ERROR retrieving operators (GEOMImpl_IHealingOperations)");
216 if ( nbOperatorErrors ) {
217 TCollection_AsciiString aMsg ("ERRORS retrieving ShapeProcess parameters (GEOMImpl_IHealingOperations): nbOperatorErrors = ");
218 aMsg += TCollection_AsciiString( nbOperatorErrors );
219 MESSAGE(aMsg.ToCString());
223 //=============================================================================
225 * GetOperatorParameters
227 //=============================================================================
228 bool GEOMImpl_IHealingOperations::GetOperatorParameters( const std::string & theOperation,
229 std::list<std::string>& theParams,
230 std::list<std::string>& theValues )
232 ShHealOper_ShapeProcess aHealer;
233 int nbParamValueErrors( 0 );
234 std::list<std::string> aParams;
235 if ( GetParameters( theOperation, aParams ) ) {
236 for ( std::list<std::string>::iterator it = aParams.begin(); it != aParams.end(); ++it ) {
237 TCollection_AsciiString aParam( (Standard_CString)(*it).c_str() );
238 TCollection_AsciiString aValue;
239 if ( aHealer.GetParameter( aParam, aValue ) ) {
240 theParams.push_back( aParam.ToCString() );
241 theValues.push_back( aValue.ToCString() );
244 nbParamValueErrors++;
250 if ( nbParamValueErrors ) {
251 TCollection_AsciiString aMsg ("ERRORS retrieving ShapeProcess parameter values (GEOMImpl_IHealingOperations): nbParamValueErrors = ");
252 aMsg += TCollection_AsciiString( nbParamValueErrors );
253 MESSAGE(aMsg.ToCString());
259 //=============================================================================
263 //=============================================================================
264 bool GEOMImpl_IHealingOperations::GetParameters (const std::string theOperation,
265 std::list<std::string>& theParams)
267 if ( theOperation == "SplitAngle" ) {
268 theParams.push_back( "SplitAngle.Angle" );
269 theParams.push_back( "SplitAngle.MaxTolerance" );
271 } else if ( theOperation == "SplitClosedFaces" ) {
272 theParams.push_back( "SplitClosedFaces.NbSplitPoints" );
274 } else if ( theOperation == "FixFaceSize" ) {
275 theParams.push_back( "FixFaceSize.Tolerance" );
277 } else if( theOperation == "DropSmallEdges" ) {
278 theParams.push_back( "DropSmallEdges.Tolerance3d" );
280 } else if( theOperation == "BSplineRestriction" ) {
281 theParams.push_back( "BSplineRestriction.SurfaceMode" );
282 theParams.push_back( "BSplineRestriction.Curve3dMode" );
283 theParams.push_back( "BSplineRestriction.Curve2dMode" );
284 theParams.push_back( "BSplineRestriction.Tolerance3d" );
285 theParams.push_back( "BSplineRestriction.Tolerance2d" );
286 theParams.push_back( "BSplineRestriction.RequiredDegree" );
287 theParams.push_back( "BSplineRestriction.RequiredNbSegments" );
288 theParams.push_back( "BSplineRestriction.Continuity3d" );
289 theParams.push_back( "BSplineRestriction.Continuity2d" );
291 } else if( theOperation == "SplitContinuity" ) {
292 theParams.push_back( "SplitContinuity.Tolerance3d" );
293 theParams.push_back( "SplitContinuity.SurfaceContinuity" );
294 theParams.push_back( "SplitContinuity.CurveContinuity" );
296 } else if( theOperation == "ToBezier" ) {
297 theParams.push_back( "ToBezier.SurfaceMode" );
298 theParams.push_back( "ToBezier.Curve3dMode" );
299 theParams.push_back( "ToBezier.Curve2dMode" );
300 theParams.push_back( "ToBezier.MaxTolerance" );
302 } else if( theOperation == "SameParameter" ) {
303 theParams.push_back( "SameParameter.Tolerance3d" );
305 } else if( theOperation == "FixShape" ) {
306 theParams.push_back( "FixShape.Tolerance3d" );
307 theParams.push_back( "FixShape.MaxTolerance3d" );
316 //=============================================================================
320 //=============================================================================
321 Handle(GEOM_Object) GEOMImpl_IHealingOperations::SuppressFaces
322 (Handle(GEOM_Object) theObject, const Handle(TColStd_HArray1OfInteger)& theFaces)
324 // set error code, check parameters
327 if (theObject.IsNull()) // if theFaces.IsNull() - it's OK, it means that ALL faces must be removed..
330 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
331 if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
334 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject(GetDocID(), GEOM_COPY);
337 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), SUPPRESS_FACES);
339 if (aFunction.IsNull()) return NULL;
341 //Check if the function is set correctly
342 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
344 // prepare "data container" class IHealing
345 GEOMImpl_IHealing HI (aFunction);
346 HI.SetFaces(theFaces);
347 HI.SetOriginal(aLastFunction);
349 //Compute the translation
352 if (!GetSolver()->ComputeFunction(aFunction))
354 SetErrorCode("Healing driver failed");
358 catch (Standard_Failure)
360 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
361 SetErrorCode(aFail->GetMessageString());
365 //Make a Python command
366 GEOM::TPythonDump pd (aFunction);
367 pd << aNewObject << " = geompy.SuppressFaces(" << theObject << ", [";
370 int i = theFaces->Lower(), nb = theFaces->Upper();
371 for ( ; i <= nb; i++)
372 pd << theFaces->Value( i ) << (( i < nb ) ? ", " : "])");
378 //=============================================================================
382 //=============================================================================
383 Handle(GEOM_Object) GEOMImpl_IHealingOperations::CloseContour
384 (Handle(GEOM_Object) theObject,
385 const Handle(TColStd_HArray1OfInteger)& theWires,
388 // set error code, check parameters
391 if (theObject.IsNull())
393 SetErrorCode("NULL object given");
397 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
398 if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
401 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
404 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), CLOSE_CONTOUR);
406 if (aFunction.IsNull()) return NULL;
408 //Check if the function is set correctly
409 if(aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
411 // prepare "data container" class IHealing
412 GEOMImpl_IHealing HI(aFunction);
413 HI.SetWires( theWires );
414 HI.SetIsCommonVertex( isCommonVertex );
415 HI.SetOriginal( aLastFunction );
417 //Compute the translation
420 if (!GetSolver()->ComputeFunction(aFunction))
422 SetErrorCode("Healing driver failed");
426 catch (Standard_Failure)
428 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
429 SetErrorCode(aFail->GetMessageString());
433 //Make a Python command
434 GEOM::TPythonDump pd (aFunction);
435 pd << aNewObject << " = geompy.CloseContour(" << theObject << ", [";
438 if (!theWires.IsNull())
440 int i = theWires->Lower(), nb = theWires->Upper();
441 pd << theWires->Value(i++);
443 pd << ", " << theWires->Value(i++);
445 pd << "], " << (int)isCommonVertex << ")";
451 //=============================================================================
455 //=============================================================================
456 Handle(GEOM_Object) GEOMImpl_IHealingOperations::RemoveIntWires
457 (Handle(GEOM_Object) theObject, const Handle(TColStd_HArray1OfInteger)& theWires)
459 // set error code, check parameters
462 if (theObject.IsNull()) // if theWires is NULL it's OK, it means that ALL wires must be removed
465 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
466 if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
469 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
472 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), REMOVE_INT_WIRES);
474 if (aFunction.IsNull()) return NULL;
476 //Check if the function is set correctly
477 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
479 // prepare "data container" class IHealing
480 GEOMImpl_IHealing HI(aFunction);
481 HI.SetWires( theWires );
482 HI.SetOriginal( aLastFunction );
484 //Compute the translation
487 if (!GetSolver()->ComputeFunction(aFunction))
489 SetErrorCode("Healing driver failed");
493 catch (Standard_Failure)
495 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
496 SetErrorCode(aFail->GetMessageString());
500 //Make a Python command
501 GEOM::TPythonDump pd (aFunction);
502 pd << aNewObject << " = geompy.SuppressInternalWires(" << theObject << ", [";
505 if (!theWires.IsNull()) {
506 int i = theWires->Lower(), nb = theWires->Upper();
507 for ( ; i <= nb; i++)
508 pd << theWires->Value( i ) << (( i < nb ) ? ", " : "])");
517 //=============================================================================
521 //=============================================================================
522 Handle(GEOM_Object) GEOMImpl_IHealingOperations::FillHoles (Handle(GEOM_Object) theObject,
523 const Handle(TColStd_HArray1OfInteger)& theWires)
525 // set error code, check parameters
528 if (theObject.IsNull()) // if theWires is NULL it's OK, it means that ALL holes must be removed
531 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
532 if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
535 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
538 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), FILL_HOLES);
540 if (aFunction.IsNull()) return NULL;
542 //Check if the function is set correctly
543 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
545 // prepare "data container" class IHealing
546 GEOMImpl_IHealing HI(aFunction);
547 HI.SetWires( theWires );
548 HI.SetOriginal( aLastFunction );
550 //Compute the translation
553 if (!GetSolver()->ComputeFunction(aFunction))
555 SetErrorCode("Healing driver failed");
559 catch (Standard_Failure)
561 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
562 SetErrorCode(aFail->GetMessageString());
566 //Make a Python command
567 GEOM::TPythonDump pd (aFunction);
568 pd << aNewObject << " = geompy.SuppressHoles(" << theObject << ", [";
571 if ( theWires.IsNull() )
574 int i = theWires->Lower(), nb = theWires->Upper();
575 for ( ; i <= nb; i++)
576 pd << theWires->Value( i ) << (( i < nb ) ? ", " : "])");
583 //=============================================================================
587 //=============================================================================
588 Handle(GEOM_Object) GEOMImpl_IHealingOperations::Sew (Handle(GEOM_Object) theObject,
590 bool isAllowNonManifold)
592 // set error code, check parameters
595 if (theObject.IsNull())
598 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
599 if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
602 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
605 int aFunctionType = (isAllowNonManifold ? SEWING_NON_MANIFOLD : SEWING);
607 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), aFunctionType);
609 if (aFunction.IsNull()) return NULL;
611 //Check if the function is set correctly
612 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
614 // prepare "data container" class IHealing
615 GEOMImpl_IHealing HI(aFunction);
616 HI.SetTolerance( theTolerance );
617 HI.SetOriginal( aLastFunction );
622 if (!GetSolver()->ComputeFunction(aFunction))
624 SetErrorCode("Healing driver failed");
628 catch (Standard_Failure) {
629 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
630 SetErrorCode(aFail->GetMessageString());
634 //Make a Python command
635 GEOM::TPythonDump pd(aFunction);
637 pd << aNewObject << " = geompy.Sew(" << theObject << ", " << theTolerance;
639 if (isAllowNonManifold) {
649 //=============================================================================
651 * RemoveInternalFaces
653 //=============================================================================
654 Handle(GEOM_Object) GEOMImpl_IHealingOperations::RemoveInternalFaces (Handle(GEOM_Object) theObject)
656 // set error code, check parameters
659 if (theObject.IsNull())
662 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
663 if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
666 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject(GetDocID(), GEOM_COPY);
669 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), REMOVE_INTERNAL_FACES);
670 if (aFunction.IsNull()) return NULL;
672 //Check if the function is set correctly
673 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
675 // prepare "data container" class IHealing
676 GEOMImpl_IHealing HI (aFunction);
677 HI.SetOriginal(aLastFunction);
682 if (!GetSolver()->ComputeFunction(aFunction))
684 SetErrorCode("Healing driver failed");
688 catch (Standard_Failure) {
689 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
690 SetErrorCode(aFail->GetMessageString());
694 //Make a Python command
695 GEOM::TPythonDump(aFunction) << aNewObject << " = geompy.RemoveInternalFaces(" << theObject << ")";
701 //=============================================================================
705 //=============================================================================
706 Handle(GEOM_Object) GEOMImpl_IHealingOperations::DivideEdge (Handle(GEOM_Object) theObject,
711 // set error code, check parameters
714 if (theObject.IsNull())
717 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
718 if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
721 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
724 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), DIVIDE_EDGE);
726 if (aFunction.IsNull()) return NULL;
728 //Check if the function is set correctly
729 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
731 // prepare "data container" class IHealing
732 GEOMImpl_IHealing HI(aFunction);
733 HI.SetIndex( theIndex );
734 HI.SetDevideEdgeValue( theValue );
735 HI.SetIsByParameter( isByParameter );
736 HI.SetOriginal( aLastFunction );
738 //Compute the translation
741 if (!GetSolver()->ComputeFunction(aFunction)) {
742 SetErrorCode("Healing driver failed");
746 catch (Standard_Failure) {
747 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
748 SetErrorCode(aFail->GetMessageString());
752 //Make a Python command
753 GEOM::TPythonDump(aFunction) << aNewObject << " = geompy.DivideEdge(" << theObject
754 << ", " << theIndex << ", " << theValue << ", " << (int)isByParameter << ")";
760 //=============================================================================
762 * FuseCollinearEdgesWithinWire
764 //=============================================================================
765 Handle(GEOM_Object) GEOMImpl_IHealingOperations::FuseCollinearEdgesWithinWire
766 (Handle(GEOM_Object) theWire,
767 std::list<Handle(GEOM_Object)> theVertices)
771 if (theWire.IsNull()) return NULL;
774 Handle(GEOM_Object) aRes = GetEngine()->AddObject(GetDocID(), theWire->GetType());
776 // Add a new function
777 Handle(GEOM_Function) aFunction;
778 aFunction = aRes->AddFunction(GEOMImpl_HealingDriver::GetID(), FUSE_COLLINEAR_EDGES);
779 if (aFunction.IsNull()) return NULL;
781 // Check if the function is set correctly
782 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
784 GEOMImpl_IHealing aCI (aFunction);
786 Handle(GEOM_Function) aRefShape = theWire->GetLastFunction();
787 if (aRefShape.IsNull()) return NULL;
788 aCI.SetOriginal(aRefShape);
790 Handle(TColStd_HSequenceOfTransient) aVertices = new TColStd_HSequenceOfTransient;
791 std::list<Handle(GEOM_Object)>::iterator it = theVertices.begin();
792 for (; it != theVertices.end(); it++) {
793 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
794 if (aRefSh.IsNull()) {
795 SetErrorCode("NULL argument shape for the shape construction");
798 aVertices->Append(aRefSh);
800 aCI.SetShapes(aVertices);
802 // Compute the new wire
805 if (!GetSolver()->ComputeFunction(aFunction)) {
806 SetErrorCode("Healing driver failed");
810 catch (Standard_Failure) {
811 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
812 SetErrorCode(aFail->GetMessageString());
816 // Make a Python command
817 GEOM::TPythonDump pd (aFunction);
818 pd << aRes << " = geompy.FuseCollinearEdgesWithinWire(" << theWire << ", [";
820 it = theVertices.begin();
821 if (it != theVertices.end()) {
823 while (it != theVertices.end()) {
824 pd << ", " << (*it++);
833 //=============================================================================
837 //=============================================================================
838 bool GEOMImpl_IHealingOperations::GetFreeBoundary (Handle(GEOM_Object) theObject,
839 Handle(TColStd_HSequenceOfTransient)& theClosed,
840 Handle(TColStd_HSequenceOfTransient)& theOpen )
842 // set error code, check parameters
845 if ( theObject.IsNull() || theClosed.IsNull() || theOpen.IsNull() )
848 TopoDS_Shape aShape = theObject->GetValue();
849 if ( aShape.IsNull() )
852 // get free boundary shapes
854 ShapeAnalysis_FreeBounds anAnalizer(aShape, Standard_False,
855 Standard_True, Standard_True);
856 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
857 TopoDS_Compound anOpen = anAnalizer.GetOpenWires();
859 // iterate through shapes and append them to the return sequence
860 Handle(GEOM_Object) anObj;
861 Handle(GEOM_Function) aFunction;
862 TopExp_Explorer anExp;
863 for ( anExp.Init( aClosed, TopAbs_WIRE ); anExp.More(); anExp.Next() )
865 anObj = GetEngine()->AddObject( GetDocID(), GEOM_FREE_BOUNDS );
866 aFunction = anObj->AddFunction( GEOMImpl_CopyDriver::GetID(), COPY_WITHOUT_REF );
867 TopoDS_Shape aValueShape = anExp.Current();
868 aFunction->SetValue( aValueShape );
869 theClosed->Append(anObj);
871 for ( anExp.Init( anOpen, TopAbs_WIRE ); anExp.More(); anExp.Next() )
873 anObj = GetEngine()->AddObject( GetDocID(), GEOM_FREE_BOUNDS );
874 aFunction = anObj->AddFunction( GEOMImpl_CopyDriver::GetID(), COPY_WITHOUT_REF );
875 TopoDS_Shape aValueShape = anExp.Current();
876 aFunction->SetValue( aValueShape );
877 theOpen->Append(anObj);
880 if(!aFunction.IsNull()) {
882 //Make a Python command
883 GEOM::TPythonDump pd (aFunction);
885 Standard_Integer i, aLen = theClosed->Length();
888 for (i = 1; i <= aLen; i++) {
889 Handle(GEOM_Object) anObj_i = Handle(GEOM_Object)::DownCast(theClosed->Value(i));
890 pd << anObj_i << ((i < aLen) ? ", " : "");
894 pd << "(isDone, empty_list, ";
897 aLen = theOpen->Length();
900 for (i = 1; i <= aLen; i++) {
901 Handle(GEOM_Object) anObj_i = Handle(GEOM_Object)::DownCast(theOpen->Value(i));
902 pd << anObj_i << ((i < aLen) ? ", " : "");
909 pd << ") = geompy.GetFreeBoundary(" << theObject << ")";
917 //=============================================================================
921 //=============================================================================
922 Handle(GEOM_Object) GEOMImpl_IHealingOperations::ChangeOrientation (Handle(GEOM_Object) theObject)
924 // set error code, check parameters
927 if (theObject.IsNull())
930 if (!theObject->IsMainShape()) {
931 SetErrorCode("Sub-shape cannot be transformed - need to create a copy");
935 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
936 if (aLastFunction.IsNull())
937 return NULL; //There is no function which creates an object to be processed
939 if (theObject->GetType() == GEOM_VECTOR) { // Mantis issue 21066
941 aFunction = theObject->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_REVERSE);
943 //Check if the function is set correctly
944 if (aFunction.IsNull()) return NULL;
945 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
947 // prepare "data container" class IVector
948 GEOMImpl_IVector aVI (aFunction);
949 aVI.SetCurve(aLastFunction);
953 aFunction = theObject->AddFunction(GEOMImpl_HealingDriver::GetID(), CHANGE_ORIENTATION);
955 //Check if the function is set correctly
956 if (aFunction.IsNull()) return NULL;
957 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
959 // prepare "data container" class IHealing
960 GEOMImpl_IHealing HI (aFunction);
961 HI.SetOriginal(aLastFunction);
964 //Compute the translation
967 if (!GetSolver()->ComputeFunction(aFunction)) {
968 SetErrorCode("Healing driver failed");
972 catch (Standard_Failure) {
973 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
974 SetErrorCode(aFail->GetMessageString());
978 //Make a Python command
979 GEOM::TPythonDump(aFunction) << "geompy.ChangeOrientationShell("
986 //=============================================================================
988 * ChangeOrientationCopy
990 //=============================================================================
991 Handle(GEOM_Object) GEOMImpl_IHealingOperations::ChangeOrientationCopy (Handle(GEOM_Object) theObject)
993 // set error code, check parameters
996 if (theObject.IsNull())
999 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
1000 if (aLastFunction.IsNull())
1001 return NULL; //There is no function which creates an object to be processed
1004 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject(GetDocID(), theObject->GetType());
1006 if (theObject->GetType() == GEOM_VECTOR) { // Mantis issue 21066
1008 aFunction = aNewObject->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_REVERSE);
1010 //Check if the function is set correctly
1011 if (aFunction.IsNull()) return NULL;
1012 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
1014 // prepare "data container" class IVector
1015 GEOMImpl_IVector aVI (aFunction);
1016 aVI.SetCurve(aLastFunction);
1020 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), CHANGE_ORIENTATION);
1022 //Check if the function is set correctly
1023 if (aFunction.IsNull()) return NULL;
1024 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
1026 // prepare "data container" class IHealing
1027 GEOMImpl_IHealing aHI (aFunction);
1028 aHI.SetOriginal(aLastFunction);
1031 // Compute the result
1034 if (!GetSolver()->ComputeFunction(aFunction)) {
1035 SetErrorCode("Healing driver failed");
1039 catch (Standard_Failure) {
1040 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1041 SetErrorCode(aFail->GetMessageString());
1045 //Make a Python command
1046 GEOM::TPythonDump(aFunction) << aNewObject << " = geompy.ChangeOrientationShellCopy("
1047 << theObject << ")";
1053 //=============================================================================
1057 //=============================================================================
1058 Handle(GEOM_Object) GEOMImpl_IHealingOperations::LimitTolerance (Handle(GEOM_Object) theObject,
1059 double theTolerance)
1061 // Set error code, check parameters
1064 if (theObject.IsNull())
1067 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
1068 if (aLastFunction.IsNull())
1069 return NULL; // There is no function which creates an object to be processed
1072 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject(GetDocID(), theObject->GetType());
1075 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), LIMIT_TOLERANCE);
1077 if (aFunction.IsNull())
1080 // Check if the function is set correctly
1081 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
1083 // Prepare "data container" class IHealing
1084 GEOMImpl_IHealing HI (aFunction);
1085 HI.SetOriginal(aLastFunction);
1086 HI.SetTolerance(theTolerance);
1091 if (!GetSolver()->ComputeFunction(aFunction)) {
1092 SetErrorCode("Healing driver failed");
1096 catch (Standard_Failure) {
1097 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1098 SetErrorCode(aFail->GetMessageString());
1102 // Make a Python command
1103 GEOM::TPythonDump(aFunction) << aNewObject << " = geompy.LimitTolerance("
1104 << theObject << ", " << theTolerance << ")";