1 // Copyright (C) 2007-2023 CEA, EDF, 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>
41 #include <Utils_ExceptHandlers.hxx>
43 #include <BRep_Builder.hxx>
44 #include <ShapeAnalysis_FreeBounds.hxx>
45 #include <TColStd_HArray1OfExtendedString.hxx>
46 #include <TColStd_HSequenceOfTransient.hxx>
47 #include <TCollection_AsciiString.hxx>
48 #include <TopExp_Explorer.hxx>
49 #include <TopTools_SequenceOfShape.hxx>
50 #include <TopoDS_Compound.hxx>
52 #include <Standard_Failure.hxx>
53 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
55 //=============================================================================
59 //=============================================================================
60 GEOMImpl_IHealingOperations::GEOMImpl_IHealingOperations (GEOM_Engine* theEngine)
61 : GEOM_IOperations(theEngine)
63 myModifStats = new ShHealOper_ModifStats;
64 MESSAGE("GEOMImpl_IHealingOperations::GEOMImpl_IHealingOperations");
67 //=============================================================================
71 //=============================================================================
72 GEOMImpl_IHealingOperations::~GEOMImpl_IHealingOperations()
75 MESSAGE("GEOMImpl_IHealingOperations::~GEOMImpl_IHealingOperations");
79 //=============================================================================
83 //=============================================================================
84 Handle(GEOM_Object) GEOMImpl_IHealingOperations::ShapeProcess (Handle(GEOM_Object) theObject,
85 const Handle(TColStd_HArray1OfExtendedString)& theOperators,
86 const Handle(TColStd_HArray1OfExtendedString)& theParams,
87 const Handle(TColStd_HArray1OfExtendedString)& theValues)
89 // set error code, check parameters
92 if (theObject.IsNull())
95 if (theOperators.IsNull() || theOperators->Length() <= 0) {
96 SetErrorCode("No operators requested");
100 Standard_Integer nbParams = 0, nbValues = 0;
101 if (!theParams.IsNull()) {
102 nbParams = theParams->Length();
104 if (!theValues.IsNull()) {
105 nbValues = theValues->Length();
108 if (nbParams != nbValues) {
109 SetErrorCode("Number of parameter values must be equal to the number of parameters");
113 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
114 if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
117 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GEOM_COPY );
120 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), SHAPE_PROCESS);
122 if (aFunction.IsNull()) return NULL;
124 //Check if the function is set correctly
125 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
127 // prepare "data container" class IHealing
128 GEOMImpl_IHealing HI(aFunction);
129 HI.SetOriginal(aLastFunction);
130 HI.SetOperators( theOperators );
132 HI.SetParameters( theParams );
133 HI.SetValues( theValues );
135 HI.SetStatistics( myModifStats );
137 //Compute the translation
140 if (!GetSolver()->ComputeFunction(aFunction))
142 SetErrorCode("Shape Healing algorithm failed");
146 catch (Standard_Failure& aFail)
148 SetErrorCode(aFail.GetMessageString());
152 //Make a Python command
153 GEOM::TPythonDump pd (aFunction);
154 pd << aNewObject << " = geompy.ProcessShape(" << theObject << ", [";
157 int i = theOperators->Lower(), nb = theOperators->Upper();
158 for ( ; i <= nb; i++) {
159 pd << "\"" << TCollection_AsciiString(theOperators->Value( i )).ToCString()
160 << (( i < nb ) ? "\", " : "\"");
163 // list of parameters
164 i = theParams->Lower(); nb = theParams->Upper();
165 for ( ; i <= nb; i++) {
166 pd << "\"" << TCollection_AsciiString(theParams->Value( i )).ToCString()
167 << (( i < nb ) ? "\", " : "\"");
171 i = theValues->Lower(); nb = theValues->Upper();
172 for ( ; i <= nb; i++) {
173 pd << "\"" << TCollection_AsciiString(theValues->Value( i )).ToCString()
174 << (( i < nb ) ? "\", " : "\"");
182 //=============================================================================
186 //=============================================================================
187 void GEOMImpl_IHealingOperations::GetShapeProcessParameters (std::list<std::string>& theOperations,
188 std::list<std::string>& theParams,
189 std::list<std::string>& theValues)
191 ShHealOper_ShapeProcess aHealer;
192 TColStd_SequenceOfAsciiString anOperators;
193 int nbOperatorErrors( 0 );
194 if ( aHealer.GetOperators( anOperators ) )
196 for ( Standard_Integer i = 1; i <= anOperators.Length(); i++ )
198 std::string anOperation = anOperators.Value( i ).ToCString();
199 if ( GetOperatorParameters( anOperation, theParams, theValues ) )
200 theOperations.push_back( anOperation );
207 SetErrorCode("ERROR retrieving operators (GEOMImpl_IHealingOperations)");
210 if ( nbOperatorErrors ) {
211 TCollection_AsciiString aMsg ("ERRORS retrieving ShapeProcess parameters (GEOMImpl_IHealingOperations): nbOperatorErrors = ");
212 aMsg += TCollection_AsciiString( nbOperatorErrors );
213 MESSAGE(aMsg.ToCString());
217 //=============================================================================
219 * GetOperatorParameters
221 //=============================================================================
222 bool GEOMImpl_IHealingOperations::GetOperatorParameters( const std::string & theOperation,
223 std::list<std::string>& theParams,
224 std::list<std::string>& theValues )
226 ShHealOper_ShapeProcess aHealer;
227 int nbParamValueErrors( 0 );
228 std::list<std::string> aParams;
229 if ( GetParameters( theOperation, aParams ) ) {
230 for ( std::list<std::string>::iterator it = aParams.begin(); it != aParams.end(); ++it ) {
231 TCollection_AsciiString aParam( (Standard_CString)(*it).c_str() );
232 TCollection_AsciiString aValue;
233 if ( aHealer.GetParameter( aParam, aValue ) ) {
234 theParams.push_back( aParam.ToCString() );
235 theValues.push_back( aValue.ToCString() );
238 nbParamValueErrors++;
244 if ( nbParamValueErrors ) {
245 TCollection_AsciiString aMsg ("ERRORS retrieving ShapeProcess parameter values (GEOMImpl_IHealingOperations): nbParamValueErrors = ");
246 aMsg += TCollection_AsciiString( nbParamValueErrors );
247 MESSAGE(aMsg.ToCString());
253 //=============================================================================
257 //=============================================================================
258 bool GEOMImpl_IHealingOperations::GetParameters (const std::string theOperation,
259 std::list<std::string>& theParams)
261 if ( theOperation == "SplitAngle" ) {
262 theParams.push_back( "SplitAngle.Angle" );
263 theParams.push_back( "SplitAngle.MaxTolerance" );
265 } else if ( theOperation == "SplitClosedFaces" ) {
266 theParams.push_back( "SplitClosedFaces.NbSplitPoints" );
268 } else if ( theOperation == "FixFaceSize" ) {
269 theParams.push_back( "FixFaceSize.Tolerance" );
271 } else if( theOperation == "DropSmallEdges" ) {
272 theParams.push_back( "DropSmallEdges.Tolerance3d" );
274 } else if( theOperation == "DropSmallSolids" ) {
275 theParams.push_back( "DropSmallSolids.WidthFactorThreshold" );
276 theParams.push_back( "DropSmallSolids.VolumeThreshold" );
277 theParams.push_back( "DropSmallSolids.MergeSolids" );
279 } else if( theOperation == "BSplineRestriction" ) {
280 theParams.push_back( "BSplineRestriction.SurfaceMode" );
281 theParams.push_back( "BSplineRestriction.Curve3dMode" );
282 theParams.push_back( "BSplineRestriction.Curve2dMode" );
283 theParams.push_back( "BSplineRestriction.Tolerance3d" );
284 theParams.push_back( "BSplineRestriction.Tolerance2d" );
285 theParams.push_back( "BSplineRestriction.RequiredDegree" );
286 theParams.push_back( "BSplineRestriction.RequiredNbSegments" );
287 theParams.push_back( "BSplineRestriction.Continuity3d" );
288 theParams.push_back( "BSplineRestriction.Continuity2d" );
290 } else if( theOperation == "SplitContinuity" ) {
291 theParams.push_back( "SplitContinuity.Tolerance3d" );
292 theParams.push_back( "SplitContinuity.SurfaceContinuity" );
293 theParams.push_back( "SplitContinuity.CurveContinuity" );
295 } else if( theOperation == "ToBezier" ) {
296 theParams.push_back( "ToBezier.SurfaceMode" );
297 theParams.push_back( "ToBezier.Curve3dMode" );
298 theParams.push_back( "ToBezier.Curve2dMode" );
299 theParams.push_back( "ToBezier.MaxTolerance" );
301 } else if( theOperation == "SameParameter" ) {
302 theParams.push_back( "SameParameter.Tolerance3d" );
304 } else if( theOperation == "FixShape" ) {
305 theParams.push_back( "FixShape.Tolerance3d" );
306 theParams.push_back( "FixShape.MaxTolerance3d" );
315 //=============================================================================
319 //=============================================================================
320 Handle(GEOM_Object) GEOMImpl_IHealingOperations::SuppressFaces
321 (Handle(GEOM_Object) theObject, const Handle(TColStd_HArray1OfInteger)& theFaces)
323 // set error code, check parameters
326 if (theObject.IsNull()) // if theFaces.IsNull() - it's OK, it means that ALL faces must be removed..
329 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
330 if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
333 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject(GEOM_COPY);
336 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), SUPPRESS_FACES);
338 if (aFunction.IsNull()) return NULL;
340 //Check if the function is set correctly
341 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
343 // prepare "data container" class IHealing
344 GEOMImpl_IHealing HI (aFunction);
345 HI.SetFaces(theFaces);
346 HI.SetOriginal(aLastFunction);
347 HI.SetStatistics( myModifStats );
349 //Compute the translation
352 if (!GetSolver()->ComputeFunction(aFunction))
354 SetErrorCode("Healing driver failed");
358 catch (Standard_Failure& aFail)
360 SetErrorCode(aFail.GetMessageString());
364 //Make a Python command
365 GEOM::TPythonDump pd (aFunction);
366 pd << aNewObject << " = geompy.SuppressFaces(" << theObject << ", [";
369 int i = theFaces->Lower(), nb = theFaces->Upper();
370 for ( ; i <= nb; i++)
371 pd << theFaces->Value( i ) << (( i < nb ) ? ", " : "])");
377 //=============================================================================
381 //=============================================================================
382 Handle(GEOM_Object) GEOMImpl_IHealingOperations::CloseContour
383 (Handle(GEOM_Object) theObject,
384 const Handle(TColStd_HArray1OfInteger)& theWires,
387 // set error code, check parameters
390 if (theObject.IsNull())
392 SetErrorCode("NULL object given");
396 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
397 if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
400 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GEOM_COPY );
403 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), CLOSE_CONTOUR);
405 if (aFunction.IsNull()) return NULL;
407 //Check if the function is set correctly
408 if(aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
410 // prepare "data container" class IHealing
411 GEOMImpl_IHealing HI(aFunction);
412 HI.SetWires( theWires );
413 HI.SetIsCommonVertex( isCommonVertex );
414 HI.SetOriginal( aLastFunction );
415 HI.SetStatistics( myModifStats );
417 //Compute the translation
420 if (!GetSolver()->ComputeFunction(aFunction))
422 SetErrorCode("Healing driver failed");
426 catch (Standard_Failure& aFail)
428 SetErrorCode(aFail.GetMessageString());
432 //Make a Python command
433 GEOM::TPythonDump pd (aFunction);
434 pd << aNewObject << " = geompy.CloseContour(" << theObject << ", [";
437 if (!theWires.IsNull())
439 int i = theWires->Lower(), nb = theWires->Upper();
440 pd << theWires->Value(i++);
442 pd << ", " << theWires->Value(i++);
444 pd << "], " << (int)isCommonVertex << ")";
450 //=============================================================================
454 //=============================================================================
455 Handle(GEOM_Object) GEOMImpl_IHealingOperations::RemoveIntWires
456 (Handle(GEOM_Object) theObject, const Handle(TColStd_HArray1OfInteger)& theWires)
458 // set error code, check parameters
461 if (theObject.IsNull()) // if theWires is NULL it's OK, it means that ALL wires must be removed
464 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
465 if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
468 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GEOM_COPY );
471 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), REMOVE_INT_WIRES);
473 if (aFunction.IsNull()) return NULL;
475 //Check if the function is set correctly
476 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
478 // prepare "data container" class IHealing
479 GEOMImpl_IHealing HI(aFunction);
480 HI.SetWires( theWires );
481 HI.SetOriginal( aLastFunction );
482 HI.SetStatistics( myModifStats );
484 //Compute the translation
487 if (!GetSolver()->ComputeFunction(aFunction))
489 SetErrorCode("Healing driver failed");
493 catch (Standard_Failure& aFail)
495 SetErrorCode(aFail.GetMessageString());
499 //Make a Python command
500 GEOM::TPythonDump pd (aFunction);
501 pd << aNewObject << " = geompy.SuppressInternalWires(" << theObject << ", [";
504 if (!theWires.IsNull()) {
505 int i = theWires->Lower(), nb = theWires->Upper();
506 for ( ; i <= nb; i++)
507 pd << theWires->Value( i ) << (( i < nb ) ? ", " : "])");
516 //=============================================================================
520 //=============================================================================
521 Handle(GEOM_Object) GEOMImpl_IHealingOperations::FillHoles (Handle(GEOM_Object) theObject,
522 const Handle(TColStd_HArray1OfInteger)& theWires)
524 // set error code, check parameters
527 if (theObject.IsNull()) // if theWires is NULL it's OK, it means that ALL holes must be removed
530 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
531 if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
534 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GEOM_COPY );
537 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), FILL_HOLES);
539 if (aFunction.IsNull()) return NULL;
541 //Check if the function is set correctly
542 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
544 // prepare "data container" class IHealing
545 GEOMImpl_IHealing HI(aFunction);
546 HI.SetWires( theWires );
547 HI.SetOriginal( aLastFunction );
548 HI.SetStatistics( myModifStats );
550 //Compute the translation
553 if (!GetSolver()->ComputeFunction(aFunction))
555 SetErrorCode("Healing driver failed");
559 catch (Standard_Failure& aFail)
561 SetErrorCode(aFail.GetMessageString());
565 //Make a Python command
566 GEOM::TPythonDump pd (aFunction);
567 pd << aNewObject << " = geompy.SuppressHoles(" << theObject << ", [";
570 if ( theWires.IsNull() )
573 int i = theWires->Lower(), nb = theWires->Upper();
574 for ( ; i <= nb; i++)
575 pd << theWires->Value( i ) << (( i < nb ) ? ", " : "])");
582 //=============================================================================
586 //=============================================================================
588 GEOMImpl_IHealingOperations::Sew (std::list<Handle(GEOM_Object)>& theObjects,
590 bool isAllowNonManifold)
592 // set error code, check parameters
595 if (theObjects.empty())
598 Handle(TColStd_HSequenceOfTransient) objects =
599 GEOM_Object::GetLastFunctions( theObjects );
600 if ( objects.IsNull() || objects->IsEmpty() ) {
601 SetErrorCode("NULL argument shape");
606 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GEOM_COPY );
609 int aFunctionType = (isAllowNonManifold ? SEWING_NON_MANIFOLD : SEWING);
610 Handle(GEOM_Function) aFunction =
611 aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), aFunctionType);
612 if (aFunction.IsNull()) return NULL;
614 //Check if the function is set correctly
615 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
617 // prepare "data container" class IHealing
618 GEOMImpl_IHealing HI(aFunction);
619 HI.SetTolerance( theTolerance );
620 HI.SetOriginal( theObjects.front()->GetLastFunction() ); objects->Remove(1);
621 HI.SetShapes( objects );
622 HI.SetStatistics( myModifStats );
627 if (!GetSolver()->ComputeFunction(aFunction))
629 SetErrorCode("Healing driver failed");
633 catch (Standard_Failure& aFail) {
634 SetErrorCode(aFail.GetMessageString());
638 //Make a Python command
639 GEOM::TPythonDump pd(aFunction);
641 pd << aNewObject << " = geompy.Sew(" << theObjects << ", " << theTolerance;
643 if (isAllowNonManifold) {
653 //=============================================================================
655 * RemoveInternalFaces
657 //=============================================================================
659 GEOMImpl_IHealingOperations::RemoveInternalFaces (std::list< Handle(GEOM_Object)> & theSolids)
661 // set error code, check parameters
664 if (theSolids.empty())
667 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theSolids );
668 if ( objects.IsNull() || objects->IsEmpty() ) {
669 SetErrorCode("NULL argument shape");
674 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject(GEOM_COPY);
677 Handle(GEOM_Function)
678 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), REMOVE_INTERNAL_FACES);
679 if (aFunction.IsNull()) return NULL;
681 //Check if the function is set correctly
682 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
684 // prepare "data container" class IHealing
685 GEOMImpl_IHealing HI (aFunction);
686 HI.SetOriginal( theSolids.front()->GetLastFunction() ); objects->Remove(1);
687 HI.SetShapes( objects );
688 HI.SetStatistics( myModifStats );
693 if (!GetSolver()->ComputeFunction(aFunction))
695 SetErrorCode("Healing driver failed");
699 catch (Standard_Failure& aFail) {
700 SetErrorCode(aFail.GetMessageString());
704 //Make a Python command
705 GEOM::TPythonDump(aFunction) << aNewObject << " = geompy.RemoveInternalFaces(" << theSolids << ")";
711 //=============================================================================
715 //=============================================================================
716 Handle(GEOM_Object) GEOMImpl_IHealingOperations::DivideEdge (Handle(GEOM_Object) theObject,
721 // set error code, check parameters
724 if (theObject.IsNull())
727 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
728 if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
731 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GEOM_COPY );
734 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), DIVIDE_EDGE);
736 if (aFunction.IsNull()) return NULL;
738 //Check if the function is set correctly
739 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
741 // prepare "data container" class IHealing
742 GEOMImpl_IHealing HI(aFunction);
743 HI.SetIndex( theIndex );
744 HI.SetDevideEdgeValue( theValue );
745 HI.SetIsByParameter( isByParameter );
746 HI.SetOriginal( aLastFunction );
747 HI.SetStatistics( myModifStats );
749 //Compute the translation
752 if (!GetSolver()->ComputeFunction(aFunction)) {
753 SetErrorCode("Healing driver failed");
757 catch (Standard_Failure& aFail) {
758 SetErrorCode(aFail.GetMessageString());
762 //Make a Python command
763 GEOM::TPythonDump(aFunction) << aNewObject << " = geompy.DivideEdge(" << theObject
764 << ", " << theIndex << ", " << theValue << ", " << (int)isByParameter << ")";
770 //=============================================================================
774 //=============================================================================
776 GEOMImpl_IHealingOperations::DivideEdgeByPoint (Handle(GEOM_Object) theObject,
778 std::list< Handle(GEOM_Object)> & thePoints)
780 // set error code, check parameters
783 if (theObject.IsNull() || thePoints.empty() )
786 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
787 if (aLastFunction.IsNull() )
788 return NULL; //There is no function which creates an object to be processed
790 Handle(TColStd_HSequenceOfTransient) aPointFunc = GEOM_Object::GetLastFunctions( thePoints );
791 if ( aPointFunc.IsNull() || aPointFunc->IsEmpty() ) {
792 SetErrorCode("NULL argument points");
797 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GEOM_COPY );
800 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), DIVIDE_EDGE_BY_POINT);
802 if (aFunction.IsNull()) return NULL;
804 //Check if the function is set correctly
805 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
807 // prepare "data container" class IHealing
808 GEOMImpl_IHealing HI(aFunction);
809 HI.SetIndex ( theIndex );
810 HI.SetOriginal ( aLastFunction );
811 HI.SetShapes ( aPointFunc );
813 HI.SetStatistics( myModifStats );
815 //Compute the translation
818 if (!GetSolver()->ComputeFunction(aFunction)) {
819 SetErrorCode("Healing driver failed");
823 catch (Standard_Failure& aFail) {
824 SetErrorCode(aFail.GetMessageString());
828 //Make a Python command
829 GEOM::TPythonDump(aFunction)
830 << aNewObject << " = geompy.DivideEdgeByPoint(" << theObject
831 << ", " << theIndex << ", " << thePoints << ")";
837 //=============================================================================
839 * FuseCollinearEdgesWithinWire
841 //=============================================================================
842 Handle(GEOM_Object) GEOMImpl_IHealingOperations::FuseCollinearEdgesWithinWire
843 (Handle(GEOM_Object) theWire,
844 std::list<Handle(GEOM_Object)> theVertices)
848 if (theWire.IsNull()) return NULL;
851 Handle(GEOM_Object) aRes = GetEngine()->AddObject(theWire->GetType());
853 // Add a new function
854 Handle(GEOM_Function) aFunction;
855 aFunction = aRes->AddFunction(GEOMImpl_HealingDriver::GetID(), FUSE_COLLINEAR_EDGES);
856 if (aFunction.IsNull()) return NULL;
858 // Check if the function is set correctly
859 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
861 GEOMImpl_IHealing aCI (aFunction);
862 aCI.SetStatistics( myModifStats );
864 Handle(GEOM_Function) aRefShape = theWire->GetLastFunction();
865 if (aRefShape.IsNull()) return NULL;
866 aCI.SetOriginal(aRefShape);
868 Handle(TColStd_HSequenceOfTransient) aVertices = new TColStd_HSequenceOfTransient;
869 std::list<Handle(GEOM_Object)>::iterator it = theVertices.begin();
870 for (; it != theVertices.end(); it++) {
871 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
872 if (aRefSh.IsNull()) {
873 SetErrorCode("NULL argument shape for the shape construction");
876 aVertices->Append(aRefSh);
878 aCI.SetShapes(aVertices);
880 // Compute the new wire
883 if (!GetSolver()->ComputeFunction(aFunction)) {
884 SetErrorCode("Healing driver failed");
888 catch (Standard_Failure& aFail) {
889 SetErrorCode(aFail.GetMessageString());
893 // Make a Python command
894 GEOM::TPythonDump pd (aFunction);
895 pd << aRes << " = geompy.FuseCollinearEdgesWithinWire(" << theWire << ", [";
897 it = theVertices.begin();
898 if (it != theVertices.end()) {
900 while (it != theVertices.end()) {
901 pd << ", " << (*it++);
910 //=============================================================================
914 //=============================================================================
915 bool GEOMImpl_IHealingOperations::GetFreeBoundary (Handle(TColStd_HSequenceOfTransient)& theObjects,
916 Handle(TColStd_HSequenceOfTransient)& theClosed,
917 Handle(TColStd_HSequenceOfTransient)& theOpen )
919 // set error code, check parameters
922 if ( theObjects.IsNull() || theObjects->Length() == 0 ||
923 theClosed.IsNull() || theOpen.IsNull() )
927 TopTools_SequenceOfShape shapes;
928 for ( int ind = 1; ind <= theObjects->Length(); ind++)
930 Handle(GEOM_Object) aRefShape = Handle(GEOM_Object)::DownCast( theObjects->Value(ind));
931 if ( aRefShape.IsNull() )
933 aShape = aRefShape->GetValue();
934 if ( aShape.IsNull() )
936 shapes.Append( aShape );
939 if ( shapes.Length() > 1 )
941 TopoDS_Compound compound;
942 BRep_Builder builder;
943 builder.MakeCompound( compound );
944 for ( int i = 1; i <= shapes.Length(); ++i )
945 builder.Add( compound, shapes( i ) );
950 // get free boundary shapes
952 ShapeAnalysis_FreeBounds anAnalizer(aShape, Standard_False,
953 Standard_True, Standard_True);
954 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
955 TopoDS_Compound anOpen = anAnalizer.GetOpenWires();
957 // iterate through shapes and append them to the return sequence
958 Handle(GEOM_Object) anObj;
959 Handle(GEOM_Function) aFunction;
960 TopExp_Explorer anExp;
961 for ( anExp.Init( aClosed, TopAbs_WIRE ); anExp.More(); anExp.Next() )
963 anObj = GetEngine()->AddObject( GEOM_FREE_BOUNDS );
964 aFunction = anObj->AddFunction( GEOMImpl_CopyDriver::GetID(), COPY_WITHOUT_REF );
965 TopoDS_Shape aValueShape = anExp.Current();
966 aFunction->SetValue( aValueShape );
967 theClosed->Append(anObj);
969 for ( anExp.Init( anOpen, TopAbs_WIRE ); anExp.More(); anExp.Next() )
971 anObj = GetEngine()->AddObject( GEOM_FREE_BOUNDS );
972 aFunction = anObj->AddFunction( GEOMImpl_CopyDriver::GetID(), COPY_WITHOUT_REF );
973 TopoDS_Shape aValueShape = anExp.Current();
974 aFunction->SetValue( aValueShape );
975 theOpen->Append(anObj);
978 if(!aFunction.IsNull()) {
980 //Make a Python command
981 GEOM::TPythonDump pd (aFunction);
983 Standard_Integer i, aLen = theClosed->Length();
986 for (i = 1; i <= aLen; i++) {
987 Handle(GEOM_Object) anObj_i = Handle(GEOM_Object)::DownCast(theClosed->Value(i));
988 pd << anObj_i << ((i < aLen) ? ", " : "");
992 pd << "(isDone, empty_list, ";
995 aLen = theOpen->Length();
998 for (i = 1; i <= aLen; i++) {
999 Handle(GEOM_Object) anObj_i = Handle(GEOM_Object)::DownCast(theOpen->Value(i));
1000 pd << anObj_i << ((i < aLen) ? ", " : "");
1007 pd << ") = geompy.GetFreeBoundary(" << theObjects << ")";
1015 //=============================================================================
1019 //=============================================================================
1020 Handle(GEOM_Object) GEOMImpl_IHealingOperations::ChangeOrientation (Handle(GEOM_Object) theObject)
1022 // set error code, check parameters
1025 if (theObject.IsNull())
1028 if (!theObject->IsMainShape()) {
1029 SetErrorCode("Sub-shape cannot be transformed - need to create a copy");
1033 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
1034 if (aLastFunction.IsNull())
1035 return NULL; //There is no function which creates an object to be processed
1037 if (theObject->GetType() == GEOM_VECTOR) { // Mantis issue 21066
1039 aFunction = theObject->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_REVERSE);
1041 //Check if the function is set correctly
1042 if (aFunction.IsNull()) return NULL;
1043 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
1045 // prepare "data container" class IVector
1046 GEOMImpl_IVector aVI (aFunction);
1047 aVI.SetCurve(aLastFunction);
1049 myModifStats->Clear();
1050 myModifStats->AddModif( "Vector reversed" );
1054 aFunction = theObject->AddFunction(GEOMImpl_HealingDriver::GetID(), CHANGE_ORIENTATION);
1056 //Check if the function is set correctly
1057 if (aFunction.IsNull()) return NULL;
1058 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
1060 // prepare "data container" class IHealing
1061 GEOMImpl_IHealing HI (aFunction);
1062 HI.SetOriginal(aLastFunction);
1063 HI.SetStatistics( myModifStats );
1066 //Compute the translation
1069 if (!GetSolver()->ComputeFunction(aFunction)) {
1070 SetErrorCode("Healing driver failed");
1074 catch (Standard_Failure& aFail) {
1075 SetErrorCode(aFail.GetMessageString());
1079 //Make a Python command
1080 GEOM::TPythonDump(aFunction) << "geompy.ChangeOrientationShell("
1081 << theObject << ")";
1087 //=============================================================================
1089 * ChangeOrientationCopy
1091 //=============================================================================
1092 Handle(GEOM_Object) GEOMImpl_IHealingOperations::ChangeOrientationCopy (Handle(GEOM_Object) theObject)
1094 // set error code, check parameters
1097 if (theObject.IsNull())
1100 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
1101 if (aLastFunction.IsNull())
1102 return NULL; //There is no function which creates an object to be processed
1105 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject(GEOM_COPY);
1107 if (theObject->GetType() == GEOM_VECTOR) { // Mantis issue 21066
1109 aFunction = aNewObject->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_REVERSE);
1111 //Check if the function is set correctly
1112 if (aFunction.IsNull()) return NULL;
1113 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
1115 // prepare "data container" class IVector
1116 GEOMImpl_IVector aVI (aFunction);
1117 aVI.SetCurve(aLastFunction);
1119 myModifStats->Clear();
1120 myModifStats->AddModif( "Vector reversed" );
1124 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), CHANGE_ORIENTATION);
1126 //Check if the function is set correctly
1127 if (aFunction.IsNull()) return NULL;
1128 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
1130 // prepare "data container" class IHealing
1131 GEOMImpl_IHealing aHI (aFunction);
1132 aHI.SetOriginal(aLastFunction);
1133 aHI.SetStatistics( myModifStats );
1136 // Compute the result
1139 if (!GetSolver()->ComputeFunction(aFunction)) {
1140 SetErrorCode("Healing driver failed");
1144 catch (Standard_Failure& aFail) {
1145 SetErrorCode(aFail.GetMessageString());
1149 //Make a Python command
1150 GEOM::TPythonDump(aFunction) << aNewObject << " = geompy.ChangeOrientationShellCopy("
1151 << theObject << ")";
1157 //=============================================================================
1161 //=============================================================================
1162 Handle(GEOM_Object) GEOMImpl_IHealingOperations::LimitTolerance (Handle(GEOM_Object) theObject,
1163 double theTolerance,
1164 TopAbs_ShapeEnum theType)
1166 // Set error code, check parameters
1169 if (theObject.IsNull())
1172 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
1173 if (aLastFunction.IsNull())
1174 return NULL; // There is no function which creates an object to be processed
1177 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject(theObject->GetType());
1180 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), LIMIT_TOLERANCE);
1182 if (aFunction.IsNull())
1185 // Check if the function is set correctly
1186 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
1188 // Prepare "data container" class IHealing
1189 GEOMImpl_IHealing HI (aFunction);
1190 HI.SetOriginal(aLastFunction);
1191 HI.SetTolerance(theTolerance);
1192 HI.SetType(theType);
1193 HI.SetStatistics( myModifStats );
1198 if (!GetSolver()->ComputeFunction(aFunction)) {
1199 SetErrorCode("Healing driver failed");
1203 catch (Standard_Failure& aFail) {
1204 SetErrorCode(aFail.GetMessageString());
1208 // Make a Python command
1209 GEOM::TPythonDump(aFunction) << aNewObject << " = geompy.LimitTolerance("
1210 << theObject << ", " << theTolerance << ")";