X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FGEOMImpl%2FGEOMImpl_IHealingOperations.cxx;h=240113ec931c7768b0eb1a29faed09ceb9c47556;hb=09ece3edc1896e16a412b35810d76411f06d68ec;hp=08e0c37579c4a127c7079e9e442890761f7cf948;hpb=150ae4647716a21d0b4797285c67e5a073262512;p=modules%2Fgeom.git diff --git a/src/GEOMImpl/GEOMImpl_IHealingOperations.cxx b/src/GEOMImpl/GEOMImpl_IHealingOperations.cxx index 08e0c3757..240113ec9 100644 --- a/src/GEOMImpl/GEOMImpl_IHealingOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IHealingOperations.cxx @@ -1,47 +1,66 @@ -#ifdef WNT +// Copyright (C) 2007-2023 CEA, EDF, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifdef WIN32 #pragma warning( disable:4786 ) #endif -#include +#include #include - #include - #include #include #include +#include +#include #include - +#include #include -#include "utilities.h" -#include +#include #include +#include #include - -#include -#include - #include #include #include +#include +#include +#include -#include - +#include #include // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC - //============================================================================= /*! * constructor: */ //============================================================================= - -GEOMImpl_IHealingOperations::GEOMImpl_IHealingOperations (GEOM_Engine* theEngine, int theDocID) -: GEOM_IOperations(theEngine, theDocID) +GEOMImpl_IHealingOperations::GEOMImpl_IHealingOperations (GEOM_Engine* theEngine) +: GEOM_IOperations(theEngine) { + myModifStats = new ShHealOper_ModifStats; MESSAGE("GEOMImpl_IHealingOperations::GEOMImpl_IHealingOperations"); } @@ -50,9 +69,9 @@ GEOMImpl_IHealingOperations::GEOMImpl_IHealingOperations (GEOM_Engine* theEngine * destructor */ //============================================================================= - GEOMImpl_IHealingOperations::~GEOMImpl_IHealingOperations() { + delete myModifStats; MESSAGE("GEOMImpl_IHealingOperations::~GEOMImpl_IHealingOperations"); } @@ -95,7 +114,7 @@ Handle(GEOM_Object) GEOMImpl_IHealingOperations::ShapeProcess (Handle(GEOM_Objec if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed // Add a new object - Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY ); + Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GEOM_COPY ); //Add the function aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), SHAPE_PROCESS); @@ -113,20 +132,20 @@ Handle(GEOM_Object) GEOMImpl_IHealingOperations::ShapeProcess (Handle(GEOM_Objec HI.SetParameters( theParams ); HI.SetValues( theValues ); } + HI.SetStatistics( myModifStats ); //Compute the translation - try - { + try { + OCC_CATCH_SIGNALS; if (!GetSolver()->ComputeFunction(aFunction)) { SetErrorCode("Shape Healing algorithm failed"); return NULL; } } - catch (Standard_Failure) + catch (Standard_Failure& aFail) { - Handle(Standard_Failure) aFail = Standard_Failure::Caught(); - SetErrorCode(aFail->GetMessageString()); + SetErrorCode(aFail.GetMessageString()); return NULL; } @@ -165,9 +184,9 @@ Handle(GEOM_Object) GEOMImpl_IHealingOperations::ShapeProcess (Handle(GEOM_Objec * ShapeProcess */ //============================================================================= -void GEOMImpl_IHealingOperations::GetShapeProcessParameters (list& theOperations, - list& theParams, - list& theValues) +void GEOMImpl_IHealingOperations::GetShapeProcessParameters (std::list& theOperations, + std::list& theParams, + std::list& theValues) { ShHealOper_ShapeProcess aHealer; TColStd_SequenceOfAsciiString anOperators; @@ -176,9 +195,9 @@ void GEOMImpl_IHealingOperations::GetShapeProcessParameters (list& theOp { for ( Standard_Integer i = 1; i <= anOperators.Length(); i++ ) { - string anOperation = anOperators.Value( i ).ToCString(); + std::string anOperation = anOperators.Value( i ).ToCString(); if ( GetOperatorParameters( anOperation, theParams, theValues ) ) - theOperations.push_back( anOperation ); + theOperations.push_back( anOperation ); else nbOperatorErrors++; } @@ -200,23 +219,23 @@ void GEOMImpl_IHealingOperations::GetShapeProcessParameters (list& theOp * GetOperatorParameters */ //============================================================================= -bool GEOMImpl_IHealingOperations::GetOperatorParameters( const string theOperation, - list& theParams, - list& theValues ) +bool GEOMImpl_IHealingOperations::GetOperatorParameters( const std::string & theOperation, + std::list& theParams, + std::list& theValues ) { ShHealOper_ShapeProcess aHealer; int nbParamValueErrors( 0 ); - list aParams; + std::list aParams; if ( GetParameters( theOperation, aParams ) ) { - for ( list::iterator it = aParams.begin(); it != aParams.end(); ++it ) { + for ( std::list::iterator it = aParams.begin(); it != aParams.end(); ++it ) { TCollection_AsciiString aParam( (Standard_CString)(*it).c_str() ); TCollection_AsciiString aValue; if ( aHealer.GetParameter( aParam, aValue ) ) { - theParams.push_back( aParam.ToCString() ); - theValues.push_back( aValue.ToCString() ); + theParams.push_back( aParam.ToCString() ); + theValues.push_back( aValue.ToCString() ); } else - nbParamValueErrors++; + nbParamValueErrors++; } } else @@ -236,8 +255,8 @@ bool GEOMImpl_IHealingOperations::GetOperatorParameters( const string theOperati * GetParameters */ //============================================================================= -bool GEOMImpl_IHealingOperations::GetParameters (const string theOperation, - list& theParams) +bool GEOMImpl_IHealingOperations::GetParameters (const std::string theOperation, + std::list& theParams) { if ( theOperation == "SplitAngle" ) { theParams.push_back( "SplitAngle.Angle" ); @@ -252,6 +271,11 @@ bool GEOMImpl_IHealingOperations::GetParameters (const string theOperation, } else if( theOperation == "DropSmallEdges" ) { theParams.push_back( "DropSmallEdges.Tolerance3d" ); + } else if( theOperation == "DropSmallSolids" ) { + theParams.push_back( "DropSmallSolids.WidthFactorThreshold" ); + theParams.push_back( "DropSmallSolids.VolumeThreshold" ); + theParams.push_back( "DropSmallSolids.MergeSolids" ); + } else if( theOperation == "BSplineRestriction" ) { theParams.push_back( "BSplineRestriction.SurfaceMode" ); theParams.push_back( "BSplineRestriction.Curve3dMode" ); @@ -299,41 +323,41 @@ Handle(GEOM_Object) GEOMImpl_IHealingOperations::SuppressFaces // set error code, check parameters SetErrorCode(KO); - if ( theObject.IsNull() ) // if theFaces.IsNull() - it's OK, it means that ALL faces must be removed.. + if (theObject.IsNull()) // if theFaces.IsNull() - it's OK, it means that ALL faces must be removed.. return NULL; Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction(); - if(aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed + if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed // Add a new object - Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY ); + Handle(GEOM_Object) aNewObject = GetEngine()->AddObject(GEOM_COPY); //Add the function aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), SUPPRESS_FACES); - if(aFunction.IsNull()) return NULL; + if (aFunction.IsNull()) return NULL; //Check if the function is set correctly - if(aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL; + if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL; // prepare "data container" class IHealing - GEOMImpl_IHealing HI(aFunction); - HI.SetFaces( theFaces ); - HI.SetOriginal( aLastFunction ); + GEOMImpl_IHealing HI (aFunction); + HI.SetFaces(theFaces); + HI.SetOriginal(aLastFunction); + HI.SetStatistics( myModifStats ); //Compute the translation - try - { + try { + OCC_CATCH_SIGNALS; if (!GetSolver()->ComputeFunction(aFunction)) { SetErrorCode("Healing driver failed"); return NULL; } } - catch (Standard_Failure) + catch (Standard_Failure& aFail) { - Handle(Standard_Failure) aFail = Standard_Failure::Caught(); - SetErrorCode(aFail->GetMessageString()); + SetErrorCode(aFail.GetMessageString()); return NULL; } @@ -350,7 +374,6 @@ Handle(GEOM_Object) GEOMImpl_IHealingOperations::SuppressFaces return aNewObject; } - //============================================================================= /*! * CloseContour @@ -374,7 +397,7 @@ Handle(GEOM_Object) GEOMImpl_IHealingOperations::CloseContour if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed // Add a new object - Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY ); + Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GEOM_COPY ); //Add the function aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), CLOSE_CONTOUR); @@ -389,20 +412,20 @@ Handle(GEOM_Object) GEOMImpl_IHealingOperations::CloseContour HI.SetWires( theWires ); HI.SetIsCommonVertex( isCommonVertex ); HI.SetOriginal( aLastFunction ); + HI.SetStatistics( myModifStats ); //Compute the translation - try - { + try { + OCC_CATCH_SIGNALS; if (!GetSolver()->ComputeFunction(aFunction)) { SetErrorCode("Healing driver failed"); return NULL; } } - catch (Standard_Failure) + catch (Standard_Failure& aFail) { - Handle(Standard_Failure) aFail = Standard_Failure::Caught(); - SetErrorCode(aFail->GetMessageString()); + SetErrorCode(aFail.GetMessageString()); return NULL; } @@ -442,7 +465,7 @@ Handle(GEOM_Object) GEOMImpl_IHealingOperations::RemoveIntWires if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed // Add a new object - Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY ); + Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GEOM_COPY ); //Add the function aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), REMOVE_INT_WIRES); @@ -456,20 +479,20 @@ Handle(GEOM_Object) GEOMImpl_IHealingOperations::RemoveIntWires GEOMImpl_IHealing HI(aFunction); HI.SetWires( theWires ); HI.SetOriginal( aLastFunction ); + HI.SetStatistics( myModifStats ); //Compute the translation - try - { + try { + OCC_CATCH_SIGNALS; if (!GetSolver()->ComputeFunction(aFunction)) { SetErrorCode("Healing driver failed"); return NULL; } } - catch (Standard_Failure) + catch (Standard_Failure& aFail) { - Handle(Standard_Failure) aFail = Standard_Failure::Caught(); - SetErrorCode(aFail->GetMessageString()); + SetErrorCode(aFail.GetMessageString()); return NULL; } @@ -508,7 +531,7 @@ Handle(GEOM_Object) GEOMImpl_IHealingOperations::FillHoles (Handle(GEOM_Object) if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed // Add a new object - Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY ); + Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GEOM_COPY ); //Add the function aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), FILL_HOLES); @@ -522,20 +545,20 @@ Handle(GEOM_Object) GEOMImpl_IHealingOperations::FillHoles (Handle(GEOM_Object) GEOMImpl_IHealing HI(aFunction); HI.SetWires( theWires ); HI.SetOriginal( aLastFunction ); + HI.SetStatistics( myModifStats ); //Compute the translation - try - { + try { + OCC_CATCH_SIGNALS; if (!GetSolver()->ComputeFunction(aFunction)) { SetErrorCode("Healing driver failed"); return NULL; } } - catch (Standard_Failure) + catch (Standard_Failure& aFail) { - Handle(Standard_Failure) aFail = Standard_Failure::Caught(); - SetErrorCode(aFail->GetMessageString()); + SetErrorCode(aFail.GetMessageString()); return NULL; } @@ -561,24 +584,31 @@ Handle(GEOM_Object) GEOMImpl_IHealingOperations::FillHoles (Handle(GEOM_Object) * Sew */ //============================================================================= -Handle(GEOM_Object) GEOMImpl_IHealingOperations::Sew (Handle(GEOM_Object) theObject, - double theTolerance) +Handle(GEOM_Object) +GEOMImpl_IHealingOperations::Sew (std::list& theObjects, + double theTolerance, + bool isAllowNonManifold) { // set error code, check parameters SetErrorCode(KO); - if (theObject.IsNull()) + if (theObjects.empty()) return NULL; - Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction(); - if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed + Handle(TColStd_HSequenceOfTransient) objects = + GEOM_Object::GetLastFunctions( theObjects ); + if ( objects.IsNull() || objects->IsEmpty() ) { + SetErrorCode("NULL argument shape"); + return NULL; + } // Add a new object - Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY ); + Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GEOM_COPY ); //Add the function - aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), SEWING); - + int aFunctionType = (isAllowNonManifold ? SEWING_NON_MANIFOLD : SEWING); + Handle(GEOM_Function) aFunction = + aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), aFunctionType); if (aFunction.IsNull()) return NULL; //Check if the function is set correctly @@ -587,27 +617,92 @@ Handle(GEOM_Object) GEOMImpl_IHealingOperations::Sew (Handle(GEOM_Object) theObj // prepare "data container" class IHealing GEOMImpl_IHealing HI(aFunction); HI.SetTolerance( theTolerance ); - HI.SetOriginal( aLastFunction ); + HI.SetOriginal( theObjects.front()->GetLastFunction() ); objects->Remove(1); + HI.SetShapes( objects ); + HI.SetStatistics( myModifStats ); - //Compute the translation - try - { + //Compute the result + try { + OCC_CATCH_SIGNALS; if (!GetSolver()->ComputeFunction(aFunction)) { SetErrorCode("Healing driver failed"); return NULL; } } - catch (Standard_Failure) - { - Handle(Standard_Failure) aFail = Standard_Failure::Caught(); - SetErrorCode(aFail->GetMessageString()); + catch (Standard_Failure& aFail) { + SetErrorCode(aFail.GetMessageString()); return NULL; } //Make a Python command - GEOM::TPythonDump(aFunction) << aNewObject << " = geompy.Sew(" - << theObject << ", " << theTolerance << ")"; + GEOM::TPythonDump pd(aFunction); + + pd << aNewObject << " = geompy.Sew(" << theObjects << ", " << theTolerance; + + if (isAllowNonManifold) { + pd << ", True"; + } + + pd << ")"; + + SetErrorCode(OK); + return aNewObject; +} + +//============================================================================= +/*! + * RemoveInternalFaces + */ +//============================================================================= +Handle(GEOM_Object) +GEOMImpl_IHealingOperations::RemoveInternalFaces (std::list< Handle(GEOM_Object)> & theSolids) +{ + // set error code, check parameters + SetErrorCode(KO); + + if (theSolids.empty()) + return NULL; + + Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theSolids ); + if ( objects.IsNull() || objects->IsEmpty() ) { + SetErrorCode("NULL argument shape"); + return NULL; + } + + // Add a new object + Handle(GEOM_Object) aNewObject = GetEngine()->AddObject(GEOM_COPY); + + //Add the function + Handle(GEOM_Function) + aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), REMOVE_INTERNAL_FACES); + if (aFunction.IsNull()) return NULL; + + //Check if the function is set correctly + if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL; + + // prepare "data container" class IHealing + GEOMImpl_IHealing HI (aFunction); + HI.SetOriginal( theSolids.front()->GetLastFunction() ); objects->Remove(1); + HI.SetShapes( objects ); + HI.SetStatistics( myModifStats ); + + //Compute the result + try { + OCC_CATCH_SIGNALS; + if (!GetSolver()->ComputeFunction(aFunction)) + { + SetErrorCode("Healing driver failed"); + return NULL; + } + } + catch (Standard_Failure& aFail) { + SetErrorCode(aFail.GetMessageString()); + return NULL; + } + + //Make a Python command + GEOM::TPythonDump(aFunction) << aNewObject << " = geompy.RemoveInternalFaces(" << theSolids << ")"; SetErrorCode(OK); return aNewObject; @@ -633,7 +728,7 @@ Handle(GEOM_Object) GEOMImpl_IHealingOperations::DivideEdge (Handle(GEOM_Object) if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed // Add a new object - Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY ); + Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GEOM_COPY ); //Add the function aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), DIVIDE_EDGE); @@ -649,20 +744,18 @@ Handle(GEOM_Object) GEOMImpl_IHealingOperations::DivideEdge (Handle(GEOM_Object) HI.SetDevideEdgeValue( theValue ); HI.SetIsByParameter( isByParameter ); HI.SetOriginal( aLastFunction ); + HI.SetStatistics( myModifStats ); //Compute the translation - try - { - if (!GetSolver()->ComputeFunction(aFunction)) - { + try { + OCC_CATCH_SIGNALS; + if (!GetSolver()->ComputeFunction(aFunction)) { SetErrorCode("Healing driver failed"); return NULL; } } - catch (Standard_Failure) - { - Handle(Standard_Failure) aFail = Standard_Failure::Caught(); - SetErrorCode(aFail->GetMessageString()); + catch (Standard_Failure& aFail) { + SetErrorCode(aFail.GetMessageString()); return NULL; } @@ -674,27 +767,190 @@ Handle(GEOM_Object) GEOMImpl_IHealingOperations::DivideEdge (Handle(GEOM_Object) return aNewObject; } +//============================================================================= +/*! + * DivideEdgeByPoint + */ +//============================================================================= +Handle(GEOM_Object) +GEOMImpl_IHealingOperations::DivideEdgeByPoint (Handle(GEOM_Object) theObject, + int theIndex, + std::list< Handle(GEOM_Object)> & thePoints) +{ + // set error code, check parameters + SetErrorCode(KO); + + if (theObject.IsNull() || thePoints.empty() ) + return NULL; + + Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction(); + if (aLastFunction.IsNull() ) + return NULL; //There is no function which creates an object to be processed + + Handle(TColStd_HSequenceOfTransient) aPointFunc = GEOM_Object::GetLastFunctions( thePoints ); + if ( aPointFunc.IsNull() || aPointFunc->IsEmpty() ) { + SetErrorCode("NULL argument points"); + return NULL; + } + + // Add a new object + Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GEOM_COPY ); + + //Add the function + aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), DIVIDE_EDGE_BY_POINT); + + if (aFunction.IsNull()) return NULL; + + //Check if the function is set correctly + if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL; + + // prepare "data container" class IHealing + GEOMImpl_IHealing HI(aFunction); + HI.SetIndex ( theIndex ); + HI.SetOriginal ( aLastFunction ); + HI.SetShapes ( aPointFunc ); + + HI.SetStatistics( myModifStats ); + + //Compute the translation + try { + OCC_CATCH_SIGNALS; + if (!GetSolver()->ComputeFunction(aFunction)) { + SetErrorCode("Healing driver failed"); + return NULL; + } + } + catch (Standard_Failure& aFail) { + SetErrorCode(aFail.GetMessageString()); + return NULL; + } + + //Make a Python command + GEOM::TPythonDump(aFunction) + << aNewObject << " = geompy.DivideEdgeByPoint(" << theObject + << ", " << theIndex << ", " << thePoints << ")"; + + SetErrorCode(OK); + return aNewObject; +} + +//============================================================================= +/*! + * FuseCollinearEdgesWithinWire + */ +//============================================================================= +Handle(GEOM_Object) GEOMImpl_IHealingOperations::FuseCollinearEdgesWithinWire + (Handle(GEOM_Object) theWire, + std::list theVertices) +{ + SetErrorCode(KO); + + if (theWire.IsNull()) return NULL; + + // Add a new object + Handle(GEOM_Object) aRes = GetEngine()->AddObject(theWire->GetType()); + + // Add a new function + Handle(GEOM_Function) aFunction; + aFunction = aRes->AddFunction(GEOMImpl_HealingDriver::GetID(), FUSE_COLLINEAR_EDGES); + if (aFunction.IsNull()) return NULL; + + // Check if the function is set correctly + if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL; + + GEOMImpl_IHealing aCI (aFunction); + aCI.SetStatistics( myModifStats ); + + Handle(GEOM_Function) aRefShape = theWire->GetLastFunction(); + if (aRefShape.IsNull()) return NULL; + aCI.SetOriginal(aRefShape); + + Handle(TColStd_HSequenceOfTransient) aVertices = new TColStd_HSequenceOfTransient; + std::list::iterator it = theVertices.begin(); + for (; it != theVertices.end(); it++) { + Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction(); + if (aRefSh.IsNull()) { + SetErrorCode("NULL argument shape for the shape construction"); + return NULL; + } + aVertices->Append(aRefSh); + } + aCI.SetShapes(aVertices); + + // Compute the new wire + try { + OCC_CATCH_SIGNALS; + if (!GetSolver()->ComputeFunction(aFunction)) { + SetErrorCode("Healing driver failed"); + return NULL; + } + } + catch (Standard_Failure& aFail) { + SetErrorCode(aFail.GetMessageString()); + return NULL; + } + + // Make a Python command + GEOM::TPythonDump pd (aFunction); + pd << aRes << " = geompy.FuseCollinearEdgesWithinWire(" << theWire << ", ["; + // Vertices + it = theVertices.begin(); + if (it != theVertices.end()) { + pd << (*it++); + while (it != theVertices.end()) { + pd << ", " << (*it++); + } + } + pd << "])"; + + SetErrorCode(OK); + return aRes; +} + //============================================================================= /*! * GetFreeBoundary */ //============================================================================= -bool GEOMImpl_IHealingOperations::GetFreeBoundary (Handle(GEOM_Object) theObject, - Handle(TColStd_HSequenceOfTransient)& theClosed, - Handle(TColStd_HSequenceOfTransient)& theOpen ) +bool GEOMImpl_IHealingOperations::GetFreeBoundary (Handle(TColStd_HSequenceOfTransient)& theObjects, + Handle(TColStd_HSequenceOfTransient)& theClosed, + Handle(TColStd_HSequenceOfTransient)& theOpen ) { // set error code, check parameters SetErrorCode(KO); - if ( theObject.IsNull() || theClosed.IsNull() || theOpen.IsNull() ) + if ( theObjects.IsNull() || theObjects->Length() == 0 || + theClosed.IsNull() || theOpen.IsNull() ) return false; - TopoDS_Shape aShape = theObject->GetValue(); - if ( aShape.IsNull() ) - return false; + TopoDS_Shape aShape; + TopTools_SequenceOfShape shapes; + for ( int ind = 1; ind <= theObjects->Length(); ind++) + { + Handle(GEOM_Object) aRefShape = Handle(GEOM_Object)::DownCast( theObjects->Value(ind)); + if ( aRefShape.IsNull() ) + return false; + aShape = aRefShape->GetValue(); + if ( aShape.IsNull() ) + return false; + shapes.Append( aShape ); + } + + if ( shapes.Length() > 1 ) + { + TopoDS_Compound compound; + BRep_Builder builder; + builder.MakeCompound( compound ); + for ( int i = 1; i <= shapes.Length(); ++i ) + builder.Add( compound, shapes( i ) ); + + aShape = compound; + } // get free boundary shapes - ShapeAnalysis_FreeBounds anAnalizer( aShape ); + + ShapeAnalysis_FreeBounds anAnalizer(aShape, Standard_False, + Standard_True, Standard_True); TopoDS_Compound aClosed = anAnalizer.GetClosedWires(); TopoDS_Compound anOpen = anAnalizer.GetOpenWires(); @@ -704,7 +960,7 @@ bool GEOMImpl_IHealingOperations::GetFreeBoundary (Handle(GEOM_Object) theObject TopExp_Explorer anExp; for ( anExp.Init( aClosed, TopAbs_WIRE ); anExp.More(); anExp.Next() ) { - anObj = GetEngine()->AddObject( GetDocID(), GEOM_FREE_BOUNDS ); + anObj = GetEngine()->AddObject( GEOM_FREE_BOUNDS ); aFunction = anObj->AddFunction( GEOMImpl_CopyDriver::GetID(), COPY_WITHOUT_REF ); TopoDS_Shape aValueShape = anExp.Current(); aFunction->SetValue( aValueShape ); @@ -712,42 +968,247 @@ bool GEOMImpl_IHealingOperations::GetFreeBoundary (Handle(GEOM_Object) theObject } for ( anExp.Init( anOpen, TopAbs_WIRE ); anExp.More(); anExp.Next() ) { - anObj = GetEngine()->AddObject( GetDocID(), GEOM_FREE_BOUNDS ); + anObj = GetEngine()->AddObject( GEOM_FREE_BOUNDS ); aFunction = anObj->AddFunction( GEOMImpl_CopyDriver::GetID(), COPY_WITHOUT_REF ); TopoDS_Shape aValueShape = anExp.Current(); aFunction->SetValue( aValueShape ); theOpen->Append(anObj); } + if(!aFunction.IsNull()) { + + //Make a Python command + GEOM::TPythonDump pd (aFunction); + + Standard_Integer i, aLen = theClosed->Length(); + if (aLen > 0) { + pd << "(isDone, ["; + for (i = 1; i <= aLen; i++) { + Handle(GEOM_Object) anObj_i = Handle(GEOM_Object)::DownCast(theClosed->Value(i)); + pd << anObj_i << ((i < aLen) ? ", " : ""); + } + pd << "], "; + } else { + pd << "(isDone, empty_list, "; + } + + aLen = theOpen->Length(); + if (aLen > 0) { + pd << "["; + for (i = 1; i <= aLen; i++) { + Handle(GEOM_Object) anObj_i = Handle(GEOM_Object)::DownCast(theOpen->Value(i)); + pd << anObj_i << ((i < aLen) ? ", " : ""); + } + pd << "]"; + } else { + pd << "empty_list"; + } + + pd << ") = geompy.GetFreeBoundary(" << theObjects << ")"; + } + + SetErrorCode(OK); + return true; +} + + +//============================================================================= +/*! + * ChangeOrientation + */ +//============================================================================= +Handle(GEOM_Object) GEOMImpl_IHealingOperations::ChangeOrientation (Handle(GEOM_Object) theObject) +{ + // set error code, check parameters + SetErrorCode(KO); + + if (theObject.IsNull()) + return NULL; + + if (!theObject->IsMainShape()) { + SetErrorCode("Sub-shape cannot be transformed - need to create a copy"); + return NULL; + } + + Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction(); + if (aLastFunction.IsNull()) + return NULL; //There is no function which creates an object to be processed + + if (theObject->GetType() == GEOM_VECTOR) { // Mantis issue 21066 + //Add the function + aFunction = theObject->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_REVERSE); + + //Check if the function is set correctly + if (aFunction.IsNull()) return NULL; + if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL; + + // prepare "data container" class IVector + GEOMImpl_IVector aVI (aFunction); + aVI.SetCurve(aLastFunction); + + myModifStats->Clear(); + myModifStats->AddModif( "Vector reversed" ); + } + else { + //Add the function + aFunction = theObject->AddFunction(GEOMImpl_HealingDriver::GetID(), CHANGE_ORIENTATION); + + //Check if the function is set correctly + if (aFunction.IsNull()) return NULL; + if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL; + + // prepare "data container" class IHealing + GEOMImpl_IHealing HI (aFunction); + HI.SetOriginal(aLastFunction); + HI.SetStatistics( myModifStats ); + } + + //Compute the translation + try { + OCC_CATCH_SIGNALS; + if (!GetSolver()->ComputeFunction(aFunction)) { + SetErrorCode("Healing driver failed"); + return NULL; + } + } + catch (Standard_Failure& aFail) { + SetErrorCode(aFail.GetMessageString()); + return NULL; + } + //Make a Python command - GEOM::TPythonDump pd (aFunction); + GEOM::TPythonDump(aFunction) << "geompy.ChangeOrientationShell(" + << theObject << ")"; + + SetErrorCode(OK); + return theObject; +} + +//============================================================================= +/*! + * ChangeOrientationCopy + */ +//============================================================================= +Handle(GEOM_Object) GEOMImpl_IHealingOperations::ChangeOrientationCopy (Handle(GEOM_Object) theObject) +{ + // set error code, check parameters + SetErrorCode(KO); + + if (theObject.IsNull()) + return NULL; - Standard_Integer i, aLen = theClosed->Length(); - if (aLen > 0) { - pd << "(isDone, ["; - for (i = 1; i <= aLen; i++) { - Handle(GEOM_Object) anObj_i = Handle(GEOM_Object)::DownCast(theClosed->Value(i)); - pd << anObj_i << ((i < aLen) ? ", " : ""); + Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction(); + if (aLastFunction.IsNull()) + return NULL; //There is no function which creates an object to be processed + + // Add a new object + Handle(GEOM_Object) aNewObject = GetEngine()->AddObject(GEOM_COPY); + + if (theObject->GetType() == GEOM_VECTOR) { // Mantis issue 21066 + //Add the function + aFunction = aNewObject->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_REVERSE); + + //Check if the function is set correctly + if (aFunction.IsNull()) return NULL; + if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL; + + // prepare "data container" class IVector + GEOMImpl_IVector aVI (aFunction); + aVI.SetCurve(aLastFunction); + + myModifStats->Clear(); + myModifStats->AddModif( "Vector reversed" ); + } + else { + //Add the function + aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), CHANGE_ORIENTATION); + + //Check if the function is set correctly + if (aFunction.IsNull()) return NULL; + if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL; + + // prepare "data container" class IHealing + GEOMImpl_IHealing aHI (aFunction); + aHI.SetOriginal(aLastFunction); + aHI.SetStatistics( myModifStats ); + } + + // Compute the result + try { + OCC_CATCH_SIGNALS; + if (!GetSolver()->ComputeFunction(aFunction)) { + SetErrorCode("Healing driver failed"); + return NULL; } - pd << "], "; - } else { - pd << "(isDone, empty_list, "; } + catch (Standard_Failure& aFail) { + SetErrorCode(aFail.GetMessageString()); + return NULL; + } + + //Make a Python command + GEOM::TPythonDump(aFunction) << aNewObject << " = geompy.ChangeOrientationShellCopy(" + << theObject << ")"; + + SetErrorCode(OK); + return aNewObject; +} + +//============================================================================= +/*! + * LimitTolerance + */ +//============================================================================= +Handle(GEOM_Object) GEOMImpl_IHealingOperations::LimitTolerance (Handle(GEOM_Object) theObject, + double theTolerance, + TopAbs_ShapeEnum theType) +{ + // Set error code, check parameters + SetErrorCode(KO); - aLen = theOpen->Length(); - if (aLen > 0) { - pd << "["; - for (i = 1; i <= aLen; i++) { - Handle(GEOM_Object) anObj_i = Handle(GEOM_Object)::DownCast(theOpen->Value(i)); - pd << anObj_i << ((i < aLen) ? ", " : ""); + if (theObject.IsNull()) + return NULL; + + Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction(); + if (aLastFunction.IsNull()) + return NULL; // There is no function which creates an object to be processed + + // Add a new object + Handle(GEOM_Object) aNewObject = GetEngine()->AddObject(theObject->GetType()); + + // Add the function + aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), LIMIT_TOLERANCE); + + if (aFunction.IsNull()) + return NULL; + + // Check if the function is set correctly + if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL; + + // Prepare "data container" class IHealing + GEOMImpl_IHealing HI (aFunction); + HI.SetOriginal(aLastFunction); + HI.SetTolerance(theTolerance); + HI.SetType(theType); + HI.SetStatistics( myModifStats ); + + // Compute + try { + OCC_CATCH_SIGNALS; + if (!GetSolver()->ComputeFunction(aFunction)) { + SetErrorCode("Healing driver failed"); + return NULL; } - pd << "]"; - } else { - pd << "empty_list"; + } + catch (Standard_Failure& aFail) { + SetErrorCode(aFail.GetMessageString()); + return NULL; } - pd << ") = geompy.GetFreeBoundary(" << theObject << ")"; + // Make a Python command + GEOM::TPythonDump(aFunction) << aNewObject << " = geompy.LimitTolerance(" + << theObject << ", " << theTolerance << ")"; SetErrorCode(OK); - return true; + return aNewObject; }