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 =
596 GEOM_Object::GetLastFunctions( theObjects );
597 if ( objects.IsNull() || objects->IsEmpty() ) {
598 SetErrorCode("NULL argument shape");
603 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
606 int aFunctionType = (isAllowNonManifold ? SEWING_NON_MANIFOLD : SEWING);
607 Handle(GEOM_Function) aFunction =
608 aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), aFunctionType);
609 if (aFunction.IsNull()) return NULL;
611 //Check if the function is set correctly
612 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
614 // prepare "data container" class IHealing
615 GEOMImpl_IHealing HI(aFunction);
616 HI.SetTolerance( theTolerance );
617 HI.SetOriginal( theObjects.front()->GetLastFunction() ); objects->Remove(1);
618 HI.SetShapes( objects );
623 if (!GetSolver()->ComputeFunction(aFunction))
625 SetErrorCode("Healing driver failed");
629 catch (Standard_Failure) {
630 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
631 SetErrorCode(aFail->GetMessageString());
635 //Make a Python command
636 GEOM::TPythonDump pd(aFunction);
638 pd << aNewObject << " = geompy.Sew(" << theObjects << ", " << theTolerance;
640 if (isAllowNonManifold) {
650 //=============================================================================
652 * RemoveInternalFaces
654 //=============================================================================
656 GEOMImpl_IHealingOperations::RemoveInternalFaces (std::list< Handle(GEOM_Object)> & theSolids)
658 // set error code, check parameters
661 if (theSolids.empty())
664 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theSolids );
665 if ( objects.IsNull() || objects->IsEmpty() ) {
666 SetErrorCode("NULL argument shape");
671 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject(GetDocID(), GEOM_COPY);
674 Handle(GEOM_Function)
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( theSolids.front()->GetLastFunction() ); objects->Remove(1);
684 HI.SetShapes( objects );
689 if (!GetSolver()->ComputeFunction(aFunction))
691 SetErrorCode("Healing driver failed");
695 catch (Standard_Failure) {
696 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
697 SetErrorCode(aFail->GetMessageString());
701 //Make a Python command
702 GEOM::TPythonDump(aFunction) << aNewObject << " = geompy.RemoveInternalFaces(" << theSolids << ")";
708 //=============================================================================
712 //=============================================================================
713 Handle(GEOM_Object) GEOMImpl_IHealingOperations::DivideEdge (Handle(GEOM_Object) theObject,
718 // set error code, check parameters
721 if (theObject.IsNull())
724 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
725 if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be processed
728 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
731 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), DIVIDE_EDGE);
733 if (aFunction.IsNull()) return NULL;
735 //Check if the function is set correctly
736 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
738 // prepare "data container" class IHealing
739 GEOMImpl_IHealing HI(aFunction);
740 HI.SetIndex( theIndex );
741 HI.SetDevideEdgeValue( theValue );
742 HI.SetIsByParameter( isByParameter );
743 HI.SetOriginal( aLastFunction );
745 //Compute the translation
748 if (!GetSolver()->ComputeFunction(aFunction)) {
749 SetErrorCode("Healing driver failed");
753 catch (Standard_Failure) {
754 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
755 SetErrorCode(aFail->GetMessageString());
759 //Make a Python command
760 GEOM::TPythonDump(aFunction) << aNewObject << " = geompy.DivideEdge(" << theObject
761 << ", " << theIndex << ", " << theValue << ", " << (int)isByParameter << ")";
767 //=============================================================================
771 //=============================================================================
773 GEOMImpl_IHealingOperations::DivideEdgeByPoint (Handle(GEOM_Object) theObject,
775 Handle(GEOM_Object) thePoint)
777 // set error code, check parameters
780 if (theObject.IsNull() || thePoint.IsNull())
783 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
784 Handle(GEOM_Function) aPointFunc = thePoint->GetLastFunction();
785 if (aLastFunction.IsNull() || aPointFunc.IsNull())
786 return NULL; //There is no function which creates an object to be processed
789 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject( GetDocID(), GEOM_COPY );
792 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), DIVIDE_EDGE_BY_POINT);
794 if (aFunction.IsNull()) return NULL;
796 //Check if the function is set correctly
797 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
799 // prepare "data container" class IHealing
800 GEOMImpl_IHealing HI(aFunction);
801 HI.SetIndex( theIndex );
802 HI.SetOriginal( aLastFunction );
804 Handle(TColStd_HSequenceOfTransient) funSeq = new TColStd_HSequenceOfTransient;
805 funSeq->Append( aPointFunc );
806 HI.SetShapes( funSeq );
808 //Compute the translation
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(aFunction)
824 << aNewObject << " = geompy.DivideEdgeByPoint(" << theObject
825 << ", " << theIndex << ", " << thePoint << ")";
831 //=============================================================================
833 * FuseCollinearEdgesWithinWire
835 //=============================================================================
836 Handle(GEOM_Object) GEOMImpl_IHealingOperations::FuseCollinearEdgesWithinWire
837 (Handle(GEOM_Object) theWire,
838 std::list<Handle(GEOM_Object)> theVertices)
842 if (theWire.IsNull()) return NULL;
845 Handle(GEOM_Object) aRes = GetEngine()->AddObject(GetDocID(), theWire->GetType());
847 // Add a new function
848 Handle(GEOM_Function) aFunction;
849 aFunction = aRes->AddFunction(GEOMImpl_HealingDriver::GetID(), FUSE_COLLINEAR_EDGES);
850 if (aFunction.IsNull()) return NULL;
852 // Check if the function is set correctly
853 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
855 GEOMImpl_IHealing aCI (aFunction);
857 Handle(GEOM_Function) aRefShape = theWire->GetLastFunction();
858 if (aRefShape.IsNull()) return NULL;
859 aCI.SetOriginal(aRefShape);
861 Handle(TColStd_HSequenceOfTransient) aVertices = new TColStd_HSequenceOfTransient;
862 std::list<Handle(GEOM_Object)>::iterator it = theVertices.begin();
863 for (; it != theVertices.end(); it++) {
864 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
865 if (aRefSh.IsNull()) {
866 SetErrorCode("NULL argument shape for the shape construction");
869 aVertices->Append(aRefSh);
871 aCI.SetShapes(aVertices);
873 // Compute the new wire
876 if (!GetSolver()->ComputeFunction(aFunction)) {
877 SetErrorCode("Healing driver failed");
881 catch (Standard_Failure) {
882 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
883 SetErrorCode(aFail->GetMessageString());
887 // Make a Python command
888 GEOM::TPythonDump pd (aFunction);
889 pd << aRes << " = geompy.FuseCollinearEdgesWithinWire(" << theWire << ", [";
891 it = theVertices.begin();
892 if (it != theVertices.end()) {
894 while (it != theVertices.end()) {
895 pd << ", " << (*it++);
904 //=============================================================================
908 //=============================================================================
909 bool GEOMImpl_IHealingOperations::GetFreeBoundary (Handle(TColStd_HSequenceOfTransient)& theObjects,
910 Handle(TColStd_HSequenceOfTransient)& theClosed,
911 Handle(TColStd_HSequenceOfTransient)& theOpen )
913 // set error code, check parameters
916 if ( theObjects.IsNull() || theObjects->Length() == 0 ||
917 theClosed.IsNull() || theOpen.IsNull() )
921 TopTools_SequenceOfShape shapes;
922 for ( int ind = 1; ind <= theObjects->Length(); ind++)
924 Handle(GEOM_Object) aRefShape = Handle(GEOM_Object)::DownCast( theObjects->Value(ind));
925 if ( aRefShape.IsNull() )
927 aShape = aRefShape->GetValue();
928 if ( aShape.IsNull() )
930 shapes.Append( aShape );
933 if ( shapes.Length() > 1 )
935 TopoDS_Compound compound;
936 BRep_Builder builder;
937 builder.MakeCompound( compound );
938 for ( int i = 1; i <= shapes.Length(); ++i )
939 builder.Add( compound, shapes( i ) );
944 // get free boundary shapes
946 ShapeAnalysis_FreeBounds anAnalizer(aShape, Standard_False,
947 Standard_True, Standard_True);
948 TopoDS_Compound aClosed = anAnalizer.GetClosedWires();
949 TopoDS_Compound anOpen = anAnalizer.GetOpenWires();
951 // iterate through shapes and append them to the return sequence
952 Handle(GEOM_Object) anObj;
953 Handle(GEOM_Function) aFunction;
954 TopExp_Explorer anExp;
955 for ( anExp.Init( aClosed, TopAbs_WIRE ); anExp.More(); anExp.Next() )
957 anObj = GetEngine()->AddObject( GetDocID(), GEOM_FREE_BOUNDS );
958 aFunction = anObj->AddFunction( GEOMImpl_CopyDriver::GetID(), COPY_WITHOUT_REF );
959 TopoDS_Shape aValueShape = anExp.Current();
960 aFunction->SetValue( aValueShape );
961 theClosed->Append(anObj);
963 for ( anExp.Init( anOpen, TopAbs_WIRE ); anExp.More(); anExp.Next() )
965 anObj = GetEngine()->AddObject( GetDocID(), GEOM_FREE_BOUNDS );
966 aFunction = anObj->AddFunction( GEOMImpl_CopyDriver::GetID(), COPY_WITHOUT_REF );
967 TopoDS_Shape aValueShape = anExp.Current();
968 aFunction->SetValue( aValueShape );
969 theOpen->Append(anObj);
972 if(!aFunction.IsNull()) {
974 //Make a Python command
975 GEOM::TPythonDump pd (aFunction);
977 Standard_Integer i, aLen = theClosed->Length();
980 for (i = 1; i <= aLen; i++) {
981 Handle(GEOM_Object) anObj_i = Handle(GEOM_Object)::DownCast(theClosed->Value(i));
982 pd << anObj_i << ((i < aLen) ? ", " : "");
986 pd << "(isDone, empty_list, ";
989 aLen = theOpen->Length();
992 for (i = 1; i <= aLen; i++) {
993 Handle(GEOM_Object) anObj_i = Handle(GEOM_Object)::DownCast(theOpen->Value(i));
994 pd << anObj_i << ((i < aLen) ? ", " : "");
1001 pd << ") = geompy.GetFreeBoundary(" << theObjects << ")";
1009 //=============================================================================
1013 //=============================================================================
1014 Handle(GEOM_Object) GEOMImpl_IHealingOperations::ChangeOrientation (Handle(GEOM_Object) theObject)
1016 // set error code, check parameters
1019 if (theObject.IsNull())
1022 if (!theObject->IsMainShape()) {
1023 SetErrorCode("Sub-shape cannot be transformed - need to create a copy");
1027 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
1028 if (aLastFunction.IsNull())
1029 return NULL; //There is no function which creates an object to be processed
1031 if (theObject->GetType() == GEOM_VECTOR) { // Mantis issue 21066
1033 aFunction = theObject->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_REVERSE);
1035 //Check if the function is set correctly
1036 if (aFunction.IsNull()) return NULL;
1037 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
1039 // prepare "data container" class IVector
1040 GEOMImpl_IVector aVI (aFunction);
1041 aVI.SetCurve(aLastFunction);
1045 aFunction = theObject->AddFunction(GEOMImpl_HealingDriver::GetID(), CHANGE_ORIENTATION);
1047 //Check if the function is set correctly
1048 if (aFunction.IsNull()) return NULL;
1049 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
1051 // prepare "data container" class IHealing
1052 GEOMImpl_IHealing HI (aFunction);
1053 HI.SetOriginal(aLastFunction);
1056 //Compute the translation
1059 if (!GetSolver()->ComputeFunction(aFunction)) {
1060 SetErrorCode("Healing driver failed");
1064 catch (Standard_Failure) {
1065 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1066 SetErrorCode(aFail->GetMessageString());
1070 //Make a Python command
1071 GEOM::TPythonDump(aFunction) << "geompy.ChangeOrientationShell("
1072 << theObject << ")";
1078 //=============================================================================
1080 * ChangeOrientationCopy
1082 //=============================================================================
1083 Handle(GEOM_Object) GEOMImpl_IHealingOperations::ChangeOrientationCopy (Handle(GEOM_Object) theObject)
1085 // set error code, check parameters
1088 if (theObject.IsNull())
1091 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
1092 if (aLastFunction.IsNull())
1093 return NULL; //There is no function which creates an object to be processed
1096 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject(GetDocID(), theObject->GetType());
1098 if (theObject->GetType() == GEOM_VECTOR) { // Mantis issue 21066
1100 aFunction = aNewObject->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_REVERSE);
1102 //Check if the function is set correctly
1103 if (aFunction.IsNull()) return NULL;
1104 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
1106 // prepare "data container" class IVector
1107 GEOMImpl_IVector aVI (aFunction);
1108 aVI.SetCurve(aLastFunction);
1112 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), CHANGE_ORIENTATION);
1114 //Check if the function is set correctly
1115 if (aFunction.IsNull()) return NULL;
1116 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
1118 // prepare "data container" class IHealing
1119 GEOMImpl_IHealing aHI (aFunction);
1120 aHI.SetOriginal(aLastFunction);
1123 // Compute the result
1126 if (!GetSolver()->ComputeFunction(aFunction)) {
1127 SetErrorCode("Healing driver failed");
1131 catch (Standard_Failure) {
1132 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1133 SetErrorCode(aFail->GetMessageString());
1137 //Make a Python command
1138 GEOM::TPythonDump(aFunction) << aNewObject << " = geompy.ChangeOrientationShellCopy("
1139 << theObject << ")";
1145 //=============================================================================
1149 //=============================================================================
1150 Handle(GEOM_Object) GEOMImpl_IHealingOperations::LimitTolerance (Handle(GEOM_Object) theObject,
1151 double theTolerance)
1153 // Set error code, check parameters
1156 if (theObject.IsNull())
1159 Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
1160 if (aLastFunction.IsNull())
1161 return NULL; // There is no function which creates an object to be processed
1164 Handle(GEOM_Object) aNewObject = GetEngine()->AddObject(GetDocID(), theObject->GetType());
1167 aFunction = aNewObject->AddFunction(GEOMImpl_HealingDriver::GetID(), LIMIT_TOLERANCE);
1169 if (aFunction.IsNull())
1172 // Check if the function is set correctly
1173 if (aFunction->GetDriverGUID() != GEOMImpl_HealingDriver::GetID()) return NULL;
1175 // Prepare "data container" class IHealing
1176 GEOMImpl_IHealing HI (aFunction);
1177 HI.SetOriginal(aLastFunction);
1178 HI.SetTolerance(theTolerance);
1183 if (!GetSolver()->ComputeFunction(aFunction)) {
1184 SetErrorCode("Healing driver failed");
1188 catch (Standard_Failure) {
1189 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1190 SetErrorCode(aFail->GetMessageString());
1194 // Make a Python command
1195 GEOM::TPythonDump(aFunction) << aNewObject << " = geompy.LimitTolerance("
1196 << theObject << ", " << theTolerance << ")";