1 // Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
24 #pragma warning( disable:4786 )
27 #include <Standard_Version.hxx>
28 #include <Standard_Stream.hxx>
30 #include <GEOMImpl_IHealingOperations.hxx>
31 #include <GEOM_PythonDump.hxx>
32 #include <GEOMImpl_HealingDriver.hxx>
33 #include <GEOMImpl_Types.hxx>
34 #include <GEOMImpl_IHealing.hxx>
35 #include <GEOMImpl_IVector.hxx>
36 #include <GEOMImpl_VectorDriver.hxx>
37 #include <GEOMImpl_CopyDriver.hxx>
39 #include <Basics_OCCTVersion.hxx>
41 #include <utilities.h>
43 #include <Utils_ExceptHandlers.hxx>
45 #include <BRep_Builder.hxx>
46 #include <ShHealOper_ShapeProcess.hxx>
47 #include <ShapeAnalysis_FreeBounds.hxx>
48 #include <TColStd_HArray1OfExtendedString.hxx>
49 #include <TColStd_HSequenceOfTransient.hxx>
50 #include <TCollection_AsciiString.hxx>
51 #include <TDF_Tool.hxx>
52 #include <TopExp_Explorer.hxx>
53 #include <TopTools_SequenceOfShape.hxx>
54 #include <TopoDS_Compound.hxx>
56 #include <Standard_Failure.hxx>
57 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
59 //=============================================================================
63 //=============================================================================
64 GEOMImpl_IHealingOperations::GEOMImpl_IHealingOperations (GEOM_Engine* theEngine, int theDocID)
65 : GEOM_IOperations(theEngine, theDocID)
67 MESSAGE("GEOMImpl_IHealingOperations::GEOMImpl_IHealingOperations");
70 //=============================================================================
74 //=============================================================================
75 GEOMImpl_IHealingOperations::~GEOMImpl_IHealingOperations()
77 MESSAGE("GEOMImpl_IHealingOperations::~GEOMImpl_IHealingOperations");
81 //=============================================================================
85 //=============================================================================
86 Handle(GEOM_Object) GEOMImpl_IHealingOperations::ShapeProcess (Handle(GEOM_Object) theObject,
87 const Handle(TColStd_HArray1OfExtendedString)& theOperators,
88 const Handle(TColStd_HArray1OfExtendedString)& theParams,
89 const Handle(TColStd_HArray1OfExtendedString)& theValues)
91 // set error code, check parameters
94 if (theObject.IsNull())
97 if (theOperators.IsNull() || theOperators->Length() <= 0) {
98 SetErrorCode("No operators requested");
102 Standard_Integer nbParams = 0, nbValues = 0;
103 if (!theParams.IsNull()) {
104 nbParams = theParams->Length();
106 if (!theValues.IsNull()) {
107 nbValues = theValues->Length();
110 if (nbParams != nbValues) {
111 SetErrorCode("Number of parameter values must be equal to the number of parameters");
115 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
116 if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
119 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
122 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), SHAPE_PROCESS);
124 if (aFunction.IsNull()) return NULL;
126 //Check if the function is set correctly
127 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
129 // prepare "data container" class IHealing
130 GEOMImpl_IHealing HI(aFunction);
131 HI.SetOriginal(aLastFunction);
132 HI.SetOperators( theOperators );
134 HI.SetParameters( theParams );
135 HI.SetValues( theValues );
138 //Compute the translation
141 if (!GetSolver()->ComputeFunction(aFunction))
143 SetErrorCode("Shape Healing algorithm failed");
147 catch (Standard_Failure)
149 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
150 SetErrorCode(aFail->GetMessageString());
154 //Make a Python command
155 GEOM::TPythonDump pd (aFunction);
156 pd << aNewObject << " = geompy.ProcessShape(" << theObject << ", [";
159 int i = theOperators->Lower(), nb = theOperators->Upper();
160 for ( ; i <= nb; i++) {
161 pd << "\"" << TCollection_AsciiString(theOperators->Value( i )).ToCString()
162 << (( i < nb ) ? "\", " : "\"");
165 // list of parameters
166 i = theParams->Lower(); nb = theParams->Upper();
167 for ( ; i <= nb; i++) {
168 pd << "\"" << TCollection_AsciiString(theParams->Value( i )).ToCString()
169 << (( i < nb ) ? "\", " : "\"");
173 i = theValues->Lower(); nb = theValues->Upper();
174 for ( ; i <= nb; i++) {
175 pd << "\"" << TCollection_AsciiString(theValues->Value( i )).ToCString()
176 << (( i < nb ) ? "\", " : "\"");
184 //=============================================================================
188 //=============================================================================
189 void GEOMImpl_IHealingOperations::GetShapeProcessParameters (std::list<std::string>& theOperations,
190 std::list<std::string>& theParams,
191 std::list<std::string>& theValues)
193 ShHealOper_ShapeProcess aHealer;
194 TColStd_SequenceOfAsciiString anOperators;
195 int nbOperatorErrors( 0 );
196 if ( aHealer.GetOperators( anOperators ) )
198 for ( Standard_Integer i = 1; i <= anOperators.Length(); i++ )
200 std::string anOperation = anOperators.Value( i ).ToCString();
201 if ( GetOperatorParameters( anOperation, theParams, theValues ) )
202 theOperations.push_back( anOperation );
209 SetErrorCode("ERROR retrieving operators (GEOMImpl_IHealingOperations)");
212 if ( nbOperatorErrors ) {
213 TCollection_AsciiString aMsg ("ERRORS retrieving ShapeProcess parameters (GEOMImpl_IHealingOperations): nbOperatorErrors = ");
214 aMsg += TCollection_AsciiString( nbOperatorErrors );
215 MESSAGE(aMsg.ToCString());
219 //=============================================================================
221 * GetOperatorParameters
223 //=============================================================================
224 bool GEOMImpl_IHealingOperations::GetOperatorParameters( const std::string & theOperation,
225 std::list<std::string>& theParams,
226 std::list<std::string>& theValues )
228 ShHealOper_ShapeProcess aHealer;
229 int nbParamValueErrors( 0 );
230 std::list<std::string> aParams;
231 if ( GetParameters( theOperation, aParams ) ) {
232 for ( std::list<std::string>::iterator it = aParams.begin(); it != aParams.end(); ++it ) {
233 TCollection_AsciiString aParam( (Standard_CString)(*it).c_str() );
234 TCollection_AsciiString aValue;
235 if ( aHealer.GetParameter( aParam, aValue ) ) {
236 theParams.push_back( aParam.ToCString() );
237 theValues.push_back( aValue.ToCString() );
240 nbParamValueErrors++;
246 if ( nbParamValueErrors ) {
247 TCollection_AsciiString aMsg ("ERRORS retrieving ShapeProcess parameter values (GEOMImpl_IHealingOperations): nbParamValueErrors = ");
248 aMsg += TCollection_AsciiString( nbParamValueErrors );
249 MESSAGE(aMsg.ToCString());
255 //=============================================================================
259 //=============================================================================
260 bool GEOMImpl_IHealingOperations::GetParameters (const std::string theOperation,
261 std::list<std::string>& theParams)
263 if ( theOperation == "SplitAngle" ) {
264 theParams.push_back( "SplitAngle.Angle" );
265 theParams.push_back( "SplitAngle.MaxTolerance" );
267 } else if ( theOperation == "SplitClosedFaces" ) {
268 theParams.push_back( "SplitClosedFaces.NbSplitPoints" );
270 } else if ( theOperation == "FixFaceSize" ) {
271 theParams.push_back( "FixFaceSize.Tolerance" );
273 } else if( theOperation == "DropSmallEdges" ) {
274 theParams.push_back( "DropSmallEdges.Tolerance3d" );
276 } else if( theOperation == "BSplineRestriction" ) {
277 theParams.push_back( "BSplineRestriction.SurfaceMode" );
278 theParams.push_back( "BSplineRestriction.Curve3dMode" );
279 theParams.push_back( "BSplineRestriction.Curve2dMode" );
280 theParams.push_back( "BSplineRestriction.Tolerance3d" );
281 theParams.push_back( "BSplineRestriction.Tolerance2d" );
282 theParams.push_back( "BSplineRestriction.RequiredDegree" );
283 theParams.push_back( "BSplineRestriction.RequiredNbSegments" );
284 theParams.push_back( "BSplineRestriction.Continuity3d" );
285 theParams.push_back( "BSplineRestriction.Continuity2d" );
287 } else if( theOperation == "SplitContinuity" ) {
288 theParams.push_back( "SplitContinuity.Tolerance3d" );
289 theParams.push_back( "SplitContinuity.SurfaceContinuity" );
290 theParams.push_back( "SplitContinuity.CurveContinuity" );
292 } else if( theOperation == "ToBezier" ) {
293 theParams.push_back( "ToBezier.SurfaceMode" );
294 theParams.push_back( "ToBezier.Curve3dMode" );
295 theParams.push_back( "ToBezier.Curve2dMode" );
296 theParams.push_back( "ToBezier.MaxTolerance" );
298 } else if( theOperation == "SameParameter" ) {
299 theParams.push_back( "SameParameter.Tolerance3d" );
301 } else if( theOperation == "FixShape" ) {
302 theParams.push_back( "FixShape.Tolerance3d" );
303 theParams.push_back( "FixShape.MaxTolerance3d" );
312 //=============================================================================
316 //=============================================================================
317 Handle(GEOM_Object) GEOMImpl_IHealingOperations::SuppressFaces
318 (Handle(GEOM_Object) theObject, const Handle(TColStd_HArray1OfInteger)& theFaces)
320 // set error code, check parameters
323 if (theObject.IsNull()) // if theFaces.IsNull() - it's OK, it means that ALL faces must be removed..
326 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
327 if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
330 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject(GetDocID(), GEOM_COPY);
333 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), SUPPRESS_FACES);
335 if (aFunction.IsNull()) return NULL;
337 //Check if the function is set correctly
338 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
340 // prepare "data container" class IHealing
341 GEOMImpl_IHealing HI (aFunction);
342 HI.SetFaces(theFaces);
343 HI.SetOriginal(aLastFunction);
345 //Compute the translation
348 if (!GetSolver()->ComputeFunction(aFunction))
350 SetErrorCode("Healing driver failed");
354 catch (Standard_Failure)
356 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
357 SetErrorCode(aFail->GetMessageString());
361 //Make a Python command
362 GEOM::TPythonDump pd (aFunction);
363 pd << aNewObject << " = geompy.SuppressFaces(" << theObject << ", [";
366 int i = theFaces->Lower(), nb = theFaces->Upper();
367 for ( ; i <= nb; i++)
368 pd << theFaces->Value( i ) << (( i < nb ) ? ", " : "])");
374 //=============================================================================
378 //=============================================================================
379 Handle(GEOM_Object) GEOMImpl_IHealingOperations::CloseContour
380 (Handle(GEOM_Object) theObject,
381 const Handle(TColStd_HArray1OfInteger)& theWires,
384 // set error code, check parameters
387 if (theObject.IsNull())
389 SetErrorCode("NULL object given");
393 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
394 if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
397 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
400 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), CLOSE_CONTOUR);
402 if (aFunction.IsNull()) return NULL;
404 //Check if the function is set correctly
405 if(aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
407 // prepare "data container" class IHealing
408 GEOMImpl_IHealing HI(aFunction);
409 HI.SetWires( theWires );
410 HI.SetIsCommonVertex( isCommonVertex );
411 HI.SetOriginal( aLastFunction );
413 //Compute the translation
416 if (!GetSolver()->ComputeFunction(aFunction))
418 SetErrorCode("Healing driver failed");
422 catch (Standard_Failure)
424 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
425 SetErrorCode(aFail->GetMessageString());
429 //Make a Python command
430 GEOM::TPythonDump pd (aFunction);
431 pd << aNewObject << " = geompy.CloseContour(" << theObject << ", [";
434 if (!theWires.IsNull())
436 int i = theWires->Lower(), nb = theWires->Upper();
437 pd << theWires->Value(i++);
439 pd << ", " << theWires->Value(i++);
441 pd << "], " << (int)isCommonVertex << ")";
447 //=============================================================================
451 //=============================================================================
452 Handle(GEOM_Object) GEOMImpl_IHealingOperations::RemoveIntWires
453 (Handle(GEOM_Object) theObject, const Handle(TColStd_HArray1OfInteger)& theWires)
455 // set error code, check parameters
458 if (theObject.IsNull()) // if theWires is NULL it's OK, it means that ALL wires must be removed
461 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
462 if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
465 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
468 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), REMOVE_INT_WIRES);
470 if (aFunction.IsNull()) return NULL;
472 //Check if the function is set correctly
473 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
475 // prepare "data container" class IHealing
476 GEOMImpl_IHealing HI(aFunction);
477 HI.SetWires( theWires );
478 HI.SetOriginal( aLastFunction );
480 //Compute the translation
483 if (!GetSolver()->ComputeFunction(aFunction))
485 SetErrorCode("Healing driver failed");
489 catch (Standard_Failure)
491 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
492 SetErrorCode(aFail->GetMessageString());
496 //Make a Python command
497 GEOM::TPythonDump pd (aFunction);
498 pd << aNewObject << " = geompy.SuppressInternalWires(" << theObject << ", [";
501 if (!theWires.IsNull()) {
502 int i = theWires->Lower(), nb = theWires->Upper();
503 for ( ; i <= nb; i++)
504 pd << theWires->Value( i ) << (( i < nb ) ? ", " : "])");
513 //=============================================================================
517 //=============================================================================
518 Handle(GEOM_Object) GEOMImpl_IHealingOperations::FillHoles (Handle(GEOM_Object) theObject,
519 const Handle(TColStd_HArray1OfInteger)& theWires)
521 // set error code, check parameters
524 if (theObject.IsNull()) // if theWires is NULL it's OK, it means that ALL holes must be removed
527 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
528 if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
531 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
534 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), FILL_HOLES);
536 if (aFunction.IsNull()) return NULL;
538 //Check if the function is set correctly
539 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
541 // prepare "data container" class IHealing
542 GEOMImpl_IHealing HI(aFunction);
543 HI.SetWires( theWires );
544 HI.SetOriginal( aLastFunction );
546 //Compute the translation
549 if (!GetSolver()->ComputeFunction(aFunction))
551 SetErrorCode("Healing driver failed");
555 catch (Standard_Failure)
557 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
558 SetErrorCode(aFail->GetMessageString());
562 //Make a Python command
563 GEOM::TPythonDump pd (aFunction);
564 pd << aNewObject << " = geompy.SuppressHoles(" << theObject << ", [";
567 if ( theWires.IsNull() )
570 int i = theWires->Lower(), nb = theWires->Upper();
571 for ( ; i <= nb; i++)
572 pd << theWires->Value( i ) << (( i < nb ) ? ", " : "])");
579 //=============================================================================
583 //=============================================================================
585 GEOMImpl_IHealingOperations::Sew (std::list<Handle(GEOM_Object)>& theObjects,
587 bool isAllowNonManifold)
589 // set error code, check parameters
592 if (theObjects.empty())
595 Handle(TColStd_HSequenceOfTransient) objects = new TColStd_HSequenceOfTransient;
596 std::list<Handle(GEOM_Object)>::iterator it = theObjects.begin();
597 for (; it != theObjects.end(); it++)
599 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
600 if (aRefSh.IsNull()) {
601 SetErrorCode("NULL argument shape");
604 objects->Append(aRefSh);
608 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
611 int aFunctionType = (isAllowNonManifold ? SEWING_NON_MANIFOLD : SEWING);
612 Handle(GEOM_Function) aFunction =
613 aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), aFunctionType);
614 if (aFunction.IsNull()) return NULL;
616 //Check if the function is set correctly
617 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
619 // prepare "data container" class IHealing
620 GEOMImpl_IHealing HI(aFunction);
621 HI.SetTolerance( theTolerance );
622 HI.SetOriginal( theObjects.front()->GetLastFunction() ); objects->Remove(1);
623 HI.SetShapes( objects );
628 if (!GetSolver()->ComputeFunction(aFunction))
630 SetErrorCode("Healing driver failed");
634 catch (Standard_Failure) {
635 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
636 SetErrorCode(aFail->GetMessageString());
640 //Make a Python command
641 GEOM::TPythonDump pd(aFunction);
643 pd << aNewObject << " = geompy.Sew(" << theObjects << ", " << theTolerance;
645 if (isAllowNonManifold) {
655 //=============================================================================
657 * RemoveInternalFaces
659 //=============================================================================
660 Handle(GEOM_Object) GEOMImpl_IHealingOperations::RemoveInternalFaces (Handle(GEOM_Object) theObject)
662 // set error code, check parameters
665 if (theObject.IsNull())
668 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
669 if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
672 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject(GetDocID(), GEOM_COPY);
675 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), REMOVE_INTERNAL_FACES);
676 if (aFunction.IsNull()) return NULL;
678 //Check if the function is set correctly
679 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
681 // prepare "data container" class IHealing
682 GEOMImpl_IHealing HI (aFunction);
683 HI.SetOriginal(aLastFunction);
688 if (!GetSolver()->ComputeFunction(aFunction))
690 SetErrorCode("Healing driver failed");
694 catch (Standard_Failure) {
695 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
696 SetErrorCode(aFail->GetMessageString());
700 //Make a Python command
701 GEOM::TPythonDump(aFunction) << aNewObject << " = geompy.RemoveInternalFaces(" << theObject << ")";
707 //=============================================================================
711 //=============================================================================
712 Handle(GEOM_Object) GEOMImpl_IHealingOperations::DivideEdge (Handle(GEOM_Object) theObject,
717 // set error code, check parameters
720 if (theObject.IsNull())
723 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
724 if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
727 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
730 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), DIVIDE_EDGE);
732 if (aFunction.IsNull()) return NULL;
734 //Check if the function is set correctly
735 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
737 // prepare "data container" class IHealing
738 GEOMImpl_IHealing HI(aFunction);
739 HI.SetIndex( theIndex );
740 HI.SetDevideEdgeValue( theValue );
741 HI.SetIsByParameter( isByParameter );
742 HI.SetOriginal( aLastFunction );
744 //Compute the translation
747 if (!GetSolver()->ComputeFunction(aFunction)) {
748 SetErrorCode("Healing driver failed");
752 catch (Standard_Failure) {
753 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
754 SetErrorCode(aFail->GetMessageString());
758 //Make a Python command
759 GEOM::TPythonDump(aFunction) << aNewObject << " = geompy.DivideEdge(" << theObject
760 << ", " << theIndex << ", " << theValue << ", " << (int)isByParameter << ")";
766 //=============================================================================
768 * FuseCollinearEdgesWithinWire
770 //=============================================================================
771 Handle(GEOM_Object) GEOMImpl_IHealingOperations::FuseCollinearEdgesWithinWire
772 (Handle(GEOM_Object) theWire,
773 std::list<Handle(GEOM_Object)> theVertices)
777 if (theWire.IsNull()) return NULL;
780 Handle(GEOM_Object) aRes = GetEngine()->AddObject(GetDocID(), theWire->GetType());
782 // Add a new function
783 Handle(GEOM_Function) aFunction;
784 aFunction = aRes->AddFunction(GEOMImpl_HealingDriver::GetID(), FUSE_COLLINEAR_EDGES);
785 if (aFunction.IsNull()) return NULL;
787 // Check if the function is set correctly
788 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
790 GEOMImpl_IHealing aCI (aFunction);
792 Handle(GEOM_Function) aRefShape = theWire->GetLastFunction();
793 if (aRefShape.IsNull()) return NULL;
794 aCI.SetOriginal(aRefShape);
796 Handle(TColStd_HSequenceOfTransient) aVertices = new TColStd_HSequenceOfTransient;
797 std::list<Handle(GEOM_Object)>::iterator it = theVertices.begin();
798 for (; it != theVertices.end(); it++) {
799 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
800 if (aRefSh.IsNull()) {
801 SetErrorCode("NULL argument shape for the shape construction");
804 aVertices->Append(aRefSh);
806 aCI.SetShapes(aVertices);
808 // Compute the new wire
811 if (!GetSolver()->ComputeFunction(aFunction)) {
812 SetErrorCode("Healing driver failed");
816 catch (Standard_Failure) {
817 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
818 SetErrorCode(aFail->GetMessageString());
822 // Make a Python command
823 GEOM::TPythonDump pd (aFunction);
824 pd << aRes << " = geompy.FuseCollinearEdgesWithinWire(" << theWire << ", [";
826 it = theVertices.begin();
827 if (it != theVertices.end()) {
829 while (it != theVertices.end()) {
830 pd << ", " << (*it++);
839 //=============================================================================
843 //=============================================================================
844 bool GEOMImpl_IHealingOperations::GetFreeBoundary (Handle(TColStd_HSequenceOfTransient)& theObjects,
845 Handle(TColStd_HSequenceOfTransient)& theClosed,
846 Handle(TColStd_HSequenceOfTransient)& theOpen )
848 // set error code, check parameters
851 if ( theObjects.IsNull() || theObjects->Length() == 0 ||
852 theClosed.IsNull() || theOpen.IsNull() )
856 TopTools_SequenceOfShape shapes;
857 for ( int ind = 1; ind <= theObjects->Length(); ind++)
859 Handle(GEOM_Object) aRefShape = Handle(GEOM_Object)::DownCast( theObjects->Value(ind));
860 if ( aRefShape.IsNull() )
862 aShape = aRefShape->GetValue();
863 if ( aShape.IsNull() )
865 shapes.Append( aShape );
868 if ( shapes.Length() > 1 )
870 TopoDS_Compound compound;
871 BRep_Builder builder;
872 builder.MakeCompound( compound );
873 for ( int i = 1; i <= shapes.Length(); ++i )
874 builder.Add( compound, shapes( i ) );
879 // get free boundary shapes
881 ShapeAnalysis_FreeBounds anAnalizer(aShape, Standard_False,
882 Standard_True, Standard_True);
883 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
884 TopoDS_Compound anOpen = anAnalizer.GetOpenWires();
886 // iterate through shapes and append them to the return sequence
887 Handle(GEOM_Object) anObj;
888 Handle(GEOM_Function) aFunction;
889 TopExp_Explorer anExp;
890 for ( anExp.Init( aClosed, TopAbs_WIRE ); anExp.More(); anExp.Next() )
892 anObj = GetEngine()->AddObject( GetDocID(), GEOM_FREE_BOUNDS );
893 aFunction = anObj->AddFunction( GEOMImpl_CopyDriver::GetID(), COPY_WITHOUT_REF );
894 TopoDS_Shape aValueShape = anExp.Current();
895 aFunction->SetValue( aValueShape );
896 theClosed->Append(anObj);
898 for ( anExp.Init( anOpen, TopAbs_WIRE ); anExp.More(); anExp.Next() )
900 anObj = GetEngine()->AddObject( GetDocID(), GEOM_FREE_BOUNDS );
901 aFunction = anObj->AddFunction( GEOMImpl_CopyDriver::GetID(), COPY_WITHOUT_REF );
902 TopoDS_Shape aValueShape = anExp.Current();
903 aFunction->SetValue( aValueShape );
904 theOpen->Append(anObj);
907 if(!aFunction.IsNull()) {
909 //Make a Python command
910 GEOM::TPythonDump pd (aFunction);
912 Standard_Integer i, aLen = theClosed->Length();
915 for (i = 1; i <= aLen; i++) {
916 Handle(GEOM_Object) anObj_i = Handle(GEOM_Object)::DownCast(theClosed->Value(i));
917 pd << anObj_i << ((i < aLen) ? ", " : "");
921 pd << "(isDone, empty_list, ";
924 aLen = theOpen->Length();
927 for (i = 1; i <= aLen; i++) {
928 Handle(GEOM_Object) anObj_i = Handle(GEOM_Object)::DownCast(theOpen->Value(i));
929 pd << anObj_i << ((i < aLen) ? ", " : "");
936 pd << ") = geompy.GetFreeBoundary(" << theObjects << ")";
944 //=============================================================================
948 //=============================================================================
949 Handle(GEOM_Object) GEOMImpl_IHealingOperations::ChangeOrientation (Handle(GEOM_Object) theObject)
951 // set error code, check parameters
954 if (theObject.IsNull())
957 if (!theObject->IsMainShape()) {
958 SetErrorCode("Sub-shape cannot be transformed - need to create a copy");
962 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
963 if (aLastFunction.IsNull())
964 return NULL; //There is no function which creates an object to be processed
966 if (theObject->GetType() == GEOM_VECTOR) { // Mantis issue 21066
968 aFunction = theObject->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_REVERSE);
970 //Check if the function is set correctly
971 if (aFunction.IsNull()) return NULL;
972 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
974 // prepare "data container" class IVector
975 GEOMImpl_IVector aVI (aFunction);
976 aVI.SetCurve(aLastFunction);
980 aFunction = theObject->AddFunction(GEOMImpl_HealingDriver::GetID(), CHANGE_ORIENTATION);
982 //Check if the function is set correctly
983 if (aFunction.IsNull()) return NULL;
984 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
986 // prepare "data container" class IHealing
987 GEOMImpl_IHealing HI (aFunction);
988 HI.SetOriginal(aLastFunction);
991 //Compute the translation
994 if (!GetSolver()->ComputeFunction(aFunction)) {
995 SetErrorCode("Healing driver failed");
999 catch (Standard_Failure) {
1000 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1001 SetErrorCode(aFail->GetMessageString());
1005 //Make a Python command
1006 GEOM::TPythonDump(aFunction) << "geompy.ChangeOrientationShell("
1007 << theObject << ")";
1013 //=============================================================================
1015 * ChangeOrientationCopy
1017 //=============================================================================
1018 Handle(GEOM_Object) GEOMImpl_IHealingOperations::ChangeOrientationCopy (Handle(GEOM_Object) theObject)
1020 // set error code, check parameters
1023 if (theObject.IsNull())
1026 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
1027 if (aLastFunction.IsNull())
1028 return NULL; //There is no function which creates an object to be processed
1031 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject(GetDocID(), theObject->GetType());
1033 if (theObject->GetType() == GEOM_VECTOR) { // Mantis issue 21066
1035 aFunction = aNewObject->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_REVERSE);
1037 //Check if the function is set correctly
1038 if (aFunction.IsNull()) return NULL;
1039 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
1041 // prepare "data container" class IVector
1042 GEOMImpl_IVector aVI (aFunction);
1043 aVI.SetCurve(aLastFunction);
1047 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), CHANGE_ORIENTATION);
1049 //Check if the function is set correctly
1050 if (aFunction.IsNull()) return NULL;
1051 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
1053 // prepare "data container" class IHealing
1054 GEOMImpl_IHealing aHI (aFunction);
1055 aHI.SetOriginal(aLastFunction);
1058 // Compute the result
1061 if (!GetSolver()->ComputeFunction(aFunction)) {
1062 SetErrorCode("Healing driver failed");
1066 catch (Standard_Failure) {
1067 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1068 SetErrorCode(aFail->GetMessageString());
1072 //Make a Python command
1073 GEOM::TPythonDump(aFunction) << aNewObject << " = geompy.ChangeOrientationShellCopy("
1074 << theObject << ")";
1080 //=============================================================================
1084 //=============================================================================
1085 Handle(GEOM_Object) GEOMImpl_IHealingOperations::LimitTolerance (Handle(GEOM_Object) theObject,
1086 double theTolerance)
1088 // Set error code, check parameters
1091 if (theObject.IsNull())
1094 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
1095 if (aLastFunction.IsNull())
1096 return NULL; // There is no function which creates an object to be processed
1099 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject(GetDocID(), theObject->GetType());
1102 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), LIMIT_TOLERANCE);
1104 if (aFunction.IsNull())
1107 // Check if the function is set correctly
1108 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
1110 // Prepare "data container" class IHealing
1111 GEOMImpl_IHealing HI (aFunction);
1112 HI.SetOriginal(aLastFunction);
1113 HI.SetTolerance(theTolerance);
1118 if (!GetSolver()->ComputeFunction(aFunction)) {
1119 SetErrorCode("Healing driver failed");
1123 catch (Standard_Failure) {
1124 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1125 SetErrorCode(aFail->GetMessageString());
1129 // Make a Python command
1130 GEOM::TPythonDump(aFunction) << aNewObject << " = geompy.LimitTolerance("
1131 << theObject << ", " << theTolerance << ")";