1 // Copyright (C) 2007-2021 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>
29 #include <GEOMImpl_IHealingOperations.hxx>
30 #include <GEOM_PythonDump.hxx>
31 #include <GEOMImpl_HealingDriver.hxx>
32 #include <GEOMImpl_Types.hxx>
33 #include <GEOMImpl_IHealing.hxx>
34 #include <GEOMImpl_IVector.hxx>
35 #include <GEOMImpl_VectorDriver.hxx>
36 #include <GEOMImpl_CopyDriver.hxx>
37 #include <ShHealOper_ModifStats.hxx>
38 #include <ShHealOper_ShapeProcess.hxx>
40 #include <utilities.h>
42 #include <Utils_ExceptHandlers.hxx>
44 #include <BRep_Builder.hxx>
45 #include <ShapeAnalysis_FreeBounds.hxx>
46 #include <TColStd_HArray1OfExtendedString.hxx>
47 #include <TColStd_HSequenceOfTransient.hxx>
48 #include <TCollection_AsciiString.hxx>
49 #include <TopExp_Explorer.hxx>
50 #include <TopTools_SequenceOfShape.hxx>
51 #include <TopoDS_Compound.hxx>
53 #include <Standard_Failure.hxx>
54 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
56 //=============================================================================
60 //=============================================================================
61 GEOMImpl_IHealingOperations::GEOMImpl_IHealingOperations (GEOM_Engine* theEngine)
62 : GEOM_IOperations(theEngine)
64 myModifStats = new ShHealOper_ModifStats;
65 MESSAGE("GEOMImpl_IHealingOperations::GEOMImpl_IHealingOperations");
68 //=============================================================================
72 //=============================================================================
73 GEOMImpl_IHealingOperations::~GEOMImpl_IHealingOperations()
76 MESSAGE("GEOMImpl_IHealingOperations::~GEOMImpl_IHealingOperations");
80 //=============================================================================
84 //=============================================================================
85 Handle(GEOM_Object) GEOMImpl_IHealingOperations::ShapeProcess (Handle(GEOM_Object) theObject,
86 const Handle(TColStd_HArray1OfExtendedString)& theOperators,
87 const Handle(TColStd_HArray1OfExtendedString)& theParams,
88 const Handle(TColStd_HArray1OfExtendedString)& theValues)
90 // set error code, check parameters
93 if (theObject.IsNull())
96 if (theOperators.IsNull() || theOperators->Length() <= 0) {
97 SetErrorCode("No operators requested");
101 Standard_Integer nbParams = 0, nbValues = 0;
102 if (!theParams.IsNull()) {
103 nbParams = theParams->Length();
105 if (!theValues.IsNull()) {
106 nbValues = theValues->Length();
109 if (nbParams != nbValues) {
110 SetErrorCode("Number of parameter values must be equal to the number of parameters");
114 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
115 if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
118 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GEOM_COPY );
121 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), SHAPE_PROCESS);
123 if (aFunction.IsNull()) return NULL;
125 //Check if the function is set correctly
126 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
128 // prepare "data container" class IHealing
129 GEOMImpl_IHealing HI(aFunction);
130 HI.SetOriginal(aLastFunction);
131 HI.SetOperators( theOperators );
133 HI.SetParameters( theParams );
134 HI.SetValues( theValues );
136 HI.SetStatistics( myModifStats );
138 //Compute the translation
141 if (!GetSolver()->ComputeFunction(aFunction))
143 SetErrorCode("Shape Healing algorithm failed");
147 catch (Standard_Failure& aFail)
149 SetErrorCode(aFail.GetMessageString());
153 //Make a Python command
154 GEOM::TPythonDump pd (aFunction);
155 pd << aNewObject << " = geompy.ProcessShape(" << theObject << ", [";
158 int i = theOperators->Lower(), nb = theOperators->Upper();
159 for ( ; i <= nb; i++) {
160 pd << "\"" << TCollection_AsciiString(theOperators->Value( i )).ToCString()
161 << (( i < nb ) ? "\", " : "\"");
164 // list of parameters
165 i = theParams->Lower(); nb = theParams->Upper();
166 for ( ; i <= nb; i++) {
167 pd << "\"" << TCollection_AsciiString(theParams->Value( i )).ToCString()
168 << (( i < nb ) ? "\", " : "\"");
172 i = theValues->Lower(); nb = theValues->Upper();
173 for ( ; i <= nb; i++) {
174 pd << "\"" << TCollection_AsciiString(theValues->Value( i )).ToCString()
175 << (( i < nb ) ? "\", " : "\"");
183 //=============================================================================
187 //=============================================================================
188 void GEOMImpl_IHealingOperations::GetShapeProcessParameters (std::list<std::string>& theOperations,
189 std::list<std::string>& theParams,
190 std::list<std::string>& theValues)
192 ShHealOper_ShapeProcess aHealer;
193 TColStd_SequenceOfAsciiString anOperators;
194 int nbOperatorErrors( 0 );
195 if ( aHealer.GetOperators( anOperators ) )
197 for ( Standard_Integer i = 1; i <= anOperators.Length(); i++ )
199 std::string anOperation = anOperators.Value( i ).ToCString();
200 if ( GetOperatorParameters( anOperation, theParams, theValues ) )
201 theOperations.push_back( anOperation );
208 SetErrorCode("ERROR retrieving operators (GEOMImpl_IHealingOperations)");
211 if ( nbOperatorErrors ) {
212 TCollection_AsciiString aMsg ("ERRORS retrieving ShapeProcess parameters (GEOMImpl_IHealingOperations): nbOperatorErrors = ");
213 aMsg += TCollection_AsciiString( nbOperatorErrors );
214 MESSAGE(aMsg.ToCString());
218 //=============================================================================
220 * GetOperatorParameters
222 //=============================================================================
223 bool GEOMImpl_IHealingOperations::GetOperatorParameters( const std::string & theOperation,
224 std::list<std::string>& theParams,
225 std::list<std::string>& theValues )
227 ShHealOper_ShapeProcess aHealer;
228 int nbParamValueErrors( 0 );
229 std::list<std::string> aParams;
230 if ( GetParameters( theOperation, aParams ) ) {
231 for ( std::list<std::string>::iterator it = aParams.begin(); it != aParams.end(); ++it ) {
232 TCollection_AsciiString aParam( (Standard_CString)(*it).c_str() );
233 TCollection_AsciiString aValue;
234 if ( aHealer.GetParameter( aParam, aValue ) ) {
235 theParams.push_back( aParam.ToCString() );
236 theValues.push_back( aValue.ToCString() );
239 nbParamValueErrors++;
245 if ( nbParamValueErrors ) {
246 TCollection_AsciiString aMsg ("ERRORS retrieving ShapeProcess parameter values (GEOMImpl_IHealingOperations): nbParamValueErrors = ");
247 aMsg += TCollection_AsciiString( nbParamValueErrors );
248 MESSAGE(aMsg.ToCString());
254 //=============================================================================
258 //=============================================================================
259 bool GEOMImpl_IHealingOperations::GetParameters (const std::string theOperation,
260 std::list<std::string>& theParams)
262 if ( theOperation == "SplitAngle" ) {
263 theParams.push_back( "SplitAngle.Angle" );
264 theParams.push_back( "SplitAngle.MaxTolerance" );
266 } else if ( theOperation == "SplitClosedFaces" ) {
267 theParams.push_back( "SplitClosedFaces.NbSplitPoints" );
269 } else if ( theOperation == "FixFaceSize" ) {
270 theParams.push_back( "FixFaceSize.Tolerance" );
272 } else if( theOperation == "DropSmallEdges" ) {
273 theParams.push_back( "DropSmallEdges.Tolerance3d" );
275 } else if( theOperation == "DropSmallSolids" ) {
276 theParams.push_back( "DropSmallSolids.WidthFactorThreshold" );
277 theParams.push_back( "DropSmallSolids.VolumeThreshold" );
278 theParams.push_back( "DropSmallSolids.MergeSolids" );
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(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);
348 HI.SetStatistics( myModifStats );
350 //Compute the translation
353 if (!GetSolver()->ComputeFunction(aFunction))
355 SetErrorCode("Healing driver failed");
359 catch (Standard_Failure& aFail)
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( 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 );
416 HI.SetStatistics( myModifStats );
418 //Compute the translation
421 if (!GetSolver()->ComputeFunction(aFunction))
423 SetErrorCode("Healing driver failed");
427 catch (Standard_Failure& aFail)
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( 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 );
483 HI.SetStatistics( myModifStats );
485 //Compute the translation
488 if (!GetSolver()->ComputeFunction(aFunction))
490 SetErrorCode("Healing driver failed");
494 catch (Standard_Failure& aFail)
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( 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 );
549 HI.SetStatistics( myModifStats );
551 //Compute the translation
554 if (!GetSolver()->ComputeFunction(aFunction))
556 SetErrorCode("Healing driver failed");
560 catch (Standard_Failure& aFail)
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 //=============================================================================
589 GEOMImpl_IHealingOperations::Sew (std::list<Handle(GEOM_Object)>& theObjects,
591 bool isAllowNonManifold)
593 // set error code, check parameters
596 if (theObjects.empty())
599 Handle(TColStd_HSequenceOfTransient) objects =
600 GEOM_Object::GetLastFunctions( theObjects );
601 if ( objects.IsNull() || objects->IsEmpty() ) {
602 SetErrorCode("NULL argument shape");
607 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GEOM_COPY );
610 int aFunctionType = (isAllowNonManifold ? SEWING_NON_MANIFOLD : SEWING);
611 Handle(GEOM_Function) aFunction =
612 aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), aFunctionType);
613 if (aFunction.IsNull()) return NULL;
615 //Check if the function is set correctly
616 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
618 // prepare "data container" class IHealing
619 GEOMImpl_IHealing HI(aFunction);
620 HI.SetTolerance( theTolerance );
621 HI.SetOriginal( theObjects.front()->GetLastFunction() ); objects->Remove(1);
622 HI.SetShapes( objects );
623 HI.SetStatistics( myModifStats );
628 if (!GetSolver()->ComputeFunction(aFunction))
630 SetErrorCode("Healing driver failed");
634 catch (Standard_Failure& aFail) {
635 SetErrorCode(aFail.GetMessageString());
639 //Make a Python command
640 GEOM::TPythonDump pd(aFunction);
642 pd << aNewObject << " = geompy.Sew(" << theObjects << ", " << theTolerance;
644 if (isAllowNonManifold) {
654 //=============================================================================
656 * RemoveInternalFaces
658 //=============================================================================
660 GEOMImpl_IHealingOperations::RemoveInternalFaces (std::list< Handle(GEOM_Object)> & theSolids)
662 // set error code, check parameters
665 if (theSolids.empty())
668 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theSolids );
669 if ( objects.IsNull() || objects->IsEmpty() ) {
670 SetErrorCode("NULL argument shape");
675 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject(GEOM_COPY);
678 Handle(GEOM_Function)
679 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), REMOVE_INTERNAL_FACES);
680 if (aFunction.IsNull()) return NULL;
682 //Check if the function is set correctly
683 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
685 // prepare "data container" class IHealing
686 GEOMImpl_IHealing HI (aFunction);
687 HI.SetOriginal( theSolids.front()->GetLastFunction() ); objects->Remove(1);
688 HI.SetShapes( objects );
689 HI.SetStatistics( myModifStats );
694 if (!GetSolver()->ComputeFunction(aFunction))
696 SetErrorCode("Healing driver failed");
700 catch (Standard_Failure& aFail) {
701 SetErrorCode(aFail.GetMessageString());
705 //Make a Python command
706 GEOM::TPythonDump(aFunction) << aNewObject << " = geompy.RemoveInternalFaces(" << theSolids << ")";
712 //=============================================================================
716 //=============================================================================
717 Handle(GEOM_Object) GEOMImpl_IHealingOperations::DivideEdge (Handle(GEOM_Object) theObject,
722 // set error code, check parameters
725 if (theObject.IsNull())
728 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
729 if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
732 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GEOM_COPY );
735 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), DIVIDE_EDGE);
737 if (aFunction.IsNull()) return NULL;
739 //Check if the function is set correctly
740 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
742 // prepare "data container" class IHealing
743 GEOMImpl_IHealing HI(aFunction);
744 HI.SetIndex( theIndex );
745 HI.SetDevideEdgeValue( theValue );
746 HI.SetIsByParameter( isByParameter );
747 HI.SetOriginal( aLastFunction );
748 HI.SetStatistics( myModifStats );
750 //Compute the translation
753 if (!GetSolver()->ComputeFunction(aFunction)) {
754 SetErrorCode("Healing driver failed");
758 catch (Standard_Failure& aFail) {
759 SetErrorCode(aFail.GetMessageString());
763 //Make a Python command
764 GEOM::TPythonDump(aFunction) << aNewObject << " = geompy.DivideEdge(" << theObject
765 << ", " << theIndex << ", " << theValue << ", " << (int)isByParameter << ")";
771 //=============================================================================
775 //=============================================================================
777 GEOMImpl_IHealingOperations::DivideEdgeByPoint (Handle(GEOM_Object) theObject,
779 std::list< Handle(GEOM_Object)> & thePoints)
781 // set error code, check parameters
784 if (theObject.IsNull() || thePoints.empty() )
787 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
788 if (aLastFunction.IsNull() )
789 return NULL; //There is no function which creates an object to be processed
791 Handle(TColStd_HSequenceOfTransient) aPointFunc = GEOM_Object::GetLastFunctions( thePoints );
792 if ( aPointFunc.IsNull() || aPointFunc->IsEmpty() ) {
793 SetErrorCode("NULL argument points");
798 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GEOM_COPY );
801 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), DIVIDE_EDGE_BY_POINT);
803 if (aFunction.IsNull()) return NULL;
805 //Check if the function is set correctly
806 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
808 // prepare "data container" class IHealing
809 GEOMImpl_IHealing HI(aFunction);
810 HI.SetIndex ( theIndex );
811 HI.SetOriginal ( aLastFunction );
812 HI.SetShapes ( aPointFunc );
814 HI.SetStatistics( myModifStats );
816 //Compute the translation
819 if (!GetSolver()->ComputeFunction(aFunction)) {
820 SetErrorCode("Healing driver failed");
824 catch (Standard_Failure& aFail) {
825 SetErrorCode(aFail.GetMessageString());
829 //Make a Python command
830 GEOM::TPythonDump(aFunction)
831 << aNewObject << " = geompy.DivideEdgeByPoint(" << theObject
832 << ", " << theIndex << ", " << thePoints << ")";
838 //=============================================================================
840 * FuseCollinearEdgesWithinWire
842 //=============================================================================
843 Handle(GEOM_Object) GEOMImpl_IHealingOperations::FuseCollinearEdgesWithinWire
844 (Handle(GEOM_Object) theWire,
845 std::list<Handle(GEOM_Object)> theVertices)
849 if (theWire.IsNull()) return NULL;
852 Handle(GEOM_Object) aRes = GetEngine()->AddObject(theWire->GetType());
854 // Add a new function
855 Handle(GEOM_Function) aFunction;
856 aFunction = aRes->AddFunction(GEOMImpl_HealingDriver::GetID(), FUSE_COLLINEAR_EDGES);
857 if (aFunction.IsNull()) return NULL;
859 // Check if the function is set correctly
860 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
862 GEOMImpl_IHealing aCI (aFunction);
863 aCI.SetStatistics( myModifStats );
865 Handle(GEOM_Function) aRefShape = theWire->GetLastFunction();
866 if (aRefShape.IsNull()) return NULL;
867 aCI.SetOriginal(aRefShape);
869 Handle(TColStd_HSequenceOfTransient) aVertices = new TColStd_HSequenceOfTransient;
870 std::list<Handle(GEOM_Object)>::iterator it = theVertices.begin();
871 for (; it != theVertices.end(); it++) {
872 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
873 if (aRefSh.IsNull()) {
874 SetErrorCode("NULL argument shape for the shape construction");
877 aVertices->Append(aRefSh);
879 aCI.SetShapes(aVertices);
881 // Compute the new wire
884 if (!GetSolver()->ComputeFunction(aFunction)) {
885 SetErrorCode("Healing driver failed");
889 catch (Standard_Failure& aFail) {
890 SetErrorCode(aFail.GetMessageString());
894 // Make a Python command
895 GEOM::TPythonDump pd (aFunction);
896 pd << aRes << " = geompy.FuseCollinearEdgesWithinWire(" << theWire << ", [";
898 it = theVertices.begin();
899 if (it != theVertices.end()) {
901 while (it != theVertices.end()) {
902 pd << ", " << (*it++);
911 //=============================================================================
915 //=============================================================================
916 bool GEOMImpl_IHealingOperations::GetFreeBoundary (Handle(TColStd_HSequenceOfTransient)& theObjects,
917 Handle(TColStd_HSequenceOfTransient)& theClosed,
918 Handle(TColStd_HSequenceOfTransient)& theOpen )
920 // set error code, check parameters
923 if ( theObjects.IsNull() || theObjects->Length() == 0 ||
924 theClosed.IsNull() || theOpen.IsNull() )
928 TopTools_SequenceOfShape shapes;
929 for ( int ind = 1; ind <= theObjects->Length(); ind++)
931 Handle(GEOM_Object) aRefShape = Handle(GEOM_Object)::DownCast( theObjects->Value(ind));
932 if ( aRefShape.IsNull() )
934 aShape = aRefShape->GetValue();
935 if ( aShape.IsNull() )
937 shapes.Append( aShape );
940 if ( shapes.Length() > 1 )
942 TopoDS_Compound compound;
943 BRep_Builder builder;
944 builder.MakeCompound( compound );
945 for ( int i = 1; i <= shapes.Length(); ++i )
946 builder.Add( compound, shapes( i ) );
951 // get free boundary shapes
953 ShapeAnalysis_FreeBounds anAnalizer(aShape, Standard_False,
954 Standard_True, Standard_True);
955 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
956 TopoDS_Compound anOpen = anAnalizer.GetOpenWires();
958 // iterate through shapes and append them to the return sequence
959 Handle(GEOM_Object) anObj;
960 Handle(GEOM_Function) aFunction;
961 TopExp_Explorer anExp;
962 for ( anExp.Init( aClosed, TopAbs_WIRE ); anExp.More(); anExp.Next() )
964 anObj = GetEngine()->AddObject( GEOM_FREE_BOUNDS );
965 aFunction = anObj->AddFunction( GEOMImpl_CopyDriver::GetID(), COPY_WITHOUT_REF );
966 TopoDS_Shape aValueShape = anExp.Current();
967 aFunction->SetValue( aValueShape );
968 theClosed->Append(anObj);
970 for ( anExp.Init( anOpen, TopAbs_WIRE ); anExp.More(); anExp.Next() )
972 anObj = GetEngine()->AddObject( GEOM_FREE_BOUNDS );
973 aFunction = anObj->AddFunction( GEOMImpl_CopyDriver::GetID(), COPY_WITHOUT_REF );
974 TopoDS_Shape aValueShape = anExp.Current();
975 aFunction->SetValue( aValueShape );
976 theOpen->Append(anObj);
979 if(!aFunction.IsNull()) {
981 //Make a Python command
982 GEOM::TPythonDump pd (aFunction);
984 Standard_Integer i, aLen = theClosed->Length();
987 for (i = 1; i <= aLen; i++) {
988 Handle(GEOM_Object) anObj_i = Handle(GEOM_Object)::DownCast(theClosed->Value(i));
989 pd << anObj_i << ((i < aLen) ? ", " : "");
993 pd << "(isDone, empty_list, ";
996 aLen = theOpen->Length();
999 for (i = 1; i <= aLen; i++) {
1000 Handle(GEOM_Object) anObj_i = Handle(GEOM_Object)::DownCast(theOpen->Value(i));
1001 pd << anObj_i << ((i < aLen) ? ", " : "");
1008 pd << ") = geompy.GetFreeBoundary(" << theObjects << ")";
1016 //=============================================================================
1020 //=============================================================================
1021 Handle(GEOM_Object) GEOMImpl_IHealingOperations::ChangeOrientation (Handle(GEOM_Object) theObject)
1023 // set error code, check parameters
1026 if (theObject.IsNull())
1029 if (!theObject->IsMainShape()) {
1030 SetErrorCode("Sub-shape cannot be transformed - need to create a copy");
1034 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
1035 if (aLastFunction.IsNull())
1036 return NULL; //There is no function which creates an object to be processed
1038 if (theObject->GetType() == GEOM_VECTOR) { // Mantis issue 21066
1040 aFunction = theObject->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_REVERSE);
1042 //Check if the function is set correctly
1043 if (aFunction.IsNull()) return NULL;
1044 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
1046 // prepare "data container" class IVector
1047 GEOMImpl_IVector aVI (aFunction);
1048 aVI.SetCurve(aLastFunction);
1050 myModifStats->Clear();
1051 myModifStats->AddModif( "Vector reversed" );
1055 aFunction = theObject->AddFunction(GEOMImpl_HealingDriver::GetID(), CHANGE_ORIENTATION);
1057 //Check if the function is set correctly
1058 if (aFunction.IsNull()) return NULL;
1059 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
1061 // prepare "data container" class IHealing
1062 GEOMImpl_IHealing HI (aFunction);
1063 HI.SetOriginal(aLastFunction);
1064 HI.SetStatistics( myModifStats );
1067 //Compute the translation
1070 if (!GetSolver()->ComputeFunction(aFunction)) {
1071 SetErrorCode("Healing driver failed");
1075 catch (Standard_Failure& aFail) {
1076 SetErrorCode(aFail.GetMessageString());
1080 //Make a Python command
1081 GEOM::TPythonDump(aFunction) << "geompy.ChangeOrientationShell("
1082 << theObject << ")";
1088 //=============================================================================
1090 * ChangeOrientationCopy
1092 //=============================================================================
1093 Handle(GEOM_Object) GEOMImpl_IHealingOperations::ChangeOrientationCopy (Handle(GEOM_Object) theObject)
1095 // set error code, check parameters
1098 if (theObject.IsNull())
1101 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
1102 if (aLastFunction.IsNull())
1103 return NULL; //There is no function which creates an object to be processed
1106 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject(GEOM_COPY);
1108 if (theObject->GetType() == GEOM_VECTOR) { // Mantis issue 21066
1110 aFunction = aNewObject->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_REVERSE);
1112 //Check if the function is set correctly
1113 if (aFunction.IsNull()) return NULL;
1114 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
1116 // prepare "data container" class IVector
1117 GEOMImpl_IVector aVI (aFunction);
1118 aVI.SetCurve(aLastFunction);
1120 myModifStats->Clear();
1121 myModifStats->AddModif( "Vector reversed" );
1125 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), CHANGE_ORIENTATION);
1127 //Check if the function is set correctly
1128 if (aFunction.IsNull()) return NULL;
1129 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
1131 // prepare "data container" class IHealing
1132 GEOMImpl_IHealing aHI (aFunction);
1133 aHI.SetOriginal(aLastFunction);
1134 aHI.SetStatistics( myModifStats );
1137 // Compute the result
1140 if (!GetSolver()->ComputeFunction(aFunction)) {
1141 SetErrorCode("Healing driver failed");
1145 catch (Standard_Failure& aFail) {
1146 SetErrorCode(aFail.GetMessageString());
1150 //Make a Python command
1151 GEOM::TPythonDump(aFunction) << aNewObject << " = geompy.ChangeOrientationShellCopy("
1152 << theObject << ")";
1158 //=============================================================================
1162 //=============================================================================
1163 Handle(GEOM_Object) GEOMImpl_IHealingOperations::LimitTolerance (Handle(GEOM_Object) theObject,
1164 double theTolerance,
1165 TopAbs_ShapeEnum theType)
1167 // Set error code, check parameters
1170 if (theObject.IsNull())
1173 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
1174 if (aLastFunction.IsNull())
1175 return NULL; // There is no function which creates an object to be processed
1178 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject(theObject->GetType());
1181 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), LIMIT_TOLERANCE);
1183 if (aFunction.IsNull())
1186 // Check if the function is set correctly
1187 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
1189 // Prepare "data container" class IHealing
1190 GEOMImpl_IHealing HI (aFunction);
1191 HI.SetOriginal(aLastFunction);
1192 HI.SetTolerance(theTolerance);
1193 HI.SetType(theType);
1194 HI.SetStatistics( myModifStats );
1199 if (!GetSolver()->ComputeFunction(aFunction)) {
1200 SetErrorCode("Healing driver failed");
1204 catch (Standard_Failure& aFail) {
1205 SetErrorCode(aFail.GetMessageString());
1209 // Make a Python command
1210 GEOM::TPythonDump(aFunction) << aNewObject << " = geompy.LimitTolerance("
1211 << theObject << ", " << theTolerance << ")";