Back to index

salome-geom  6.5.0
GEOMImpl_IBooleanOperations.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 #include <Standard_Stream.hxx>
00024 
00025 #include <GEOMImpl_IBooleanOperations.hxx>
00026 
00027 #include <GEOM_Function.hxx>
00028 #include <GEOM_PythonDump.hxx>
00029 
00030 #include <GEOMImpl_Types.hxx>
00031 
00032 #include <GEOMImpl_BooleanDriver.hxx>
00033 #include <GEOMImpl_IBoolean.hxx>
00034 
00035 #include <GEOMImpl_PartitionDriver.hxx>
00036 #include <GEOMImpl_IPartition.hxx>
00037 
00038 #include <Basics_OCCTVersion.hxx>
00039 
00040 #include <TDF_Tool.hxx>
00041 
00042 #include "utilities.h"
00043 
00044 #include <Standard_Failure.hxx>
00045 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
00046 
00047 //=============================================================================
00051 //=============================================================================
00052 GEOMImpl_IBooleanOperations::GEOMImpl_IBooleanOperations (GEOM_Engine* theEngine, int theDocID)
00053 : GEOM_IOperations(theEngine, theDocID)
00054 {
00055   MESSAGE("GEOMImpl_IBooleanOperations::GEOMImpl_IBooleanOperations");
00056 }
00057 
00058 //=============================================================================
00062 //=============================================================================
00063 GEOMImpl_IBooleanOperations::~GEOMImpl_IBooleanOperations()
00064 {
00065   MESSAGE("GEOMImpl_IBooleanOperations::~GEOMImpl_IBooleanOperations");
00066 }
00067 
00068 
00069 //=============================================================================
00073 //=============================================================================
00074 Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakeBoolean (Handle(GEOM_Object) theShape1,
00075                                                               Handle(GEOM_Object) theShape2,
00076                                                               Standard_Integer    theOp)
00077 {
00078   SetErrorCode(KO);
00079 
00080   if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
00081 
00082   //Add a new Boolean object
00083   Handle(GEOM_Object) aBool = GetEngine()->AddObject(GetDocID(), GEOM_BOOLEAN);
00084 
00085   //Add a new Boolean function
00086   Handle(GEOM_Function) aFunction;
00087   if (theOp == 1) {
00088     aFunction = aBool->AddFunction(GEOMImpl_BooleanDriver::GetID(), BOOLEAN_COMMON);
00089   } else if (theOp == 2) {
00090     aFunction = aBool->AddFunction(GEOMImpl_BooleanDriver::GetID(), BOOLEAN_CUT);
00091   } else if (theOp == 3) {
00092     aFunction = aBool->AddFunction(GEOMImpl_BooleanDriver::GetID(), BOOLEAN_FUSE);
00093   } else if (theOp == 4) {
00094     aFunction = aBool->AddFunction(GEOMImpl_BooleanDriver::GetID(), BOOLEAN_SECTION);
00095   } else {
00096   }
00097   if (aFunction.IsNull()) return NULL;
00098 
00099   //Check if the function is set correctly
00100   if (aFunction->GetDriverGUID() != GEOMImpl_BooleanDriver::GetID()) return NULL;
00101 
00102   GEOMImpl_IBoolean aCI (aFunction);
00103 
00104   Handle(GEOM_Function) aRef1 = theShape1->GetLastFunction();
00105   Handle(GEOM_Function) aRef2 = theShape2->GetLastFunction();
00106 
00107   if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
00108 
00109   aCI.SetShape1(aRef1);
00110   aCI.SetShape2(aRef2);
00111 
00112   //Compute the Boolean value
00113   try {
00114 #if OCC_VERSION_LARGE > 0x06010000
00115     OCC_CATCH_SIGNALS;
00116 #endif
00117     if (!GetSolver()->ComputeFunction(aFunction)) {
00118       SetErrorCode("Boolean driver failed");
00119       return NULL;
00120     }
00121   }
00122   catch (Standard_Failure) {
00123     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
00124     SetErrorCode(aFail->GetMessageString());
00125     return NULL;
00126   }
00127 
00128   //Make a Python command
00129   GEOM::TPythonDump pd (aFunction);
00130   pd << aBool;
00131   if      (theOp == 1) pd << " = geompy.MakeCommon(";
00132   else if (theOp == 2) pd << " = geompy.MakeCut(";
00133   else if (theOp == 3) pd << " = geompy.MakeFuse(";
00134   else if (theOp == 4) pd << " = geompy.MakeSection(";
00135   else {}
00136   pd << theShape1 << ", " << theShape2 << ")";
00137 
00138   SetErrorCode(OK);
00139   return aBool;
00140 }
00141 
00142 //=============================================================================
00146 //=============================================================================
00147 Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakePartition
00148                              (const Handle(TColStd_HSequenceOfTransient)& theShapes,
00149                               const Handle(TColStd_HSequenceOfTransient)& theTools,
00150                               const Handle(TColStd_HSequenceOfTransient)& theKeepIns,
00151                               const Handle(TColStd_HSequenceOfTransient)& theRemoveIns,
00152                               const Standard_Integer                      theLimit,
00153                               const Standard_Boolean                      theRemoveWebs,
00154                               const Handle(TColStd_HArray1OfInteger)&     theMaterials,
00155                               const Standard_Integer theKeepNonlimitShapes,
00156                               const Standard_Boolean thePerformSelfIntersections)
00157 {
00158   SetErrorCode(KO);
00159 
00160   //Add a new Partition object
00161   Handle(GEOM_Object) aPartition = GetEngine()->AddObject(GetDocID(), GEOM_PARTITION);
00162 
00163   //Add a new Partition function
00164   Handle(GEOM_Function) aFunction;
00165   if (thePerformSelfIntersections)
00166     aFunction = aPartition->AddFunction(GEOMImpl_PartitionDriver::GetID(), PARTITION_PARTITION);
00167   else
00168     aFunction = aPartition->AddFunction(GEOMImpl_PartitionDriver::GetID(), PARTITION_NO_SELF_INTERSECTIONS);
00169   if (aFunction.IsNull()) return NULL;
00170 
00171   //Check if the function is set correctly
00172   if (aFunction->GetDriverGUID() != GEOMImpl_PartitionDriver::GetID()) return NULL;
00173 
00174   GEOMImpl_IPartition aCI (aFunction);
00175 
00176   Handle(TColStd_HSequenceOfTransient) aShapesSeq  = new TColStd_HSequenceOfTransient;
00177   Handle(TColStd_HSequenceOfTransient) aToolsSeq   = new TColStd_HSequenceOfTransient;
00178   Handle(TColStd_HSequenceOfTransient) aKeepInsSeq = new TColStd_HSequenceOfTransient;
00179   Handle(TColStd_HSequenceOfTransient) aRemInsSeq  = new TColStd_HSequenceOfTransient;
00180 
00181   Standard_Integer ind, aLen;
00182   TCollection_AsciiString anEntry;
00183   TCollection_AsciiString aShapesDescr, aToolsDescr, aKeepInsDescr, aRemoveInsDescr;
00184 
00185   // Shapes
00186   aLen = theShapes->Length();
00187   for (ind = 1; ind <= aLen; ind++) {
00188     Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(theShapes->Value(ind));
00189     Handle(GEOM_Function) aRefSh = anObj->GetLastFunction();
00190     if (aRefSh.IsNull()) {
00191       SetErrorCode("NULL shape for Partition");
00192       return NULL;
00193     }
00194     aShapesSeq->Append(aRefSh);
00195 
00196     // For Python command
00197     TDF_Tool::Entry(anObj->GetEntry(), anEntry);
00198     if (ind > 1) aShapesDescr += ", ";
00199     aShapesDescr += anEntry;
00200   }
00201   aCI.SetShapes(aShapesSeq);
00202 
00203   // Tools
00204   aLen = theTools->Length();
00205   for (ind = 1; ind <= aLen; ind++) {
00206     Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(theTools->Value(ind));
00207     Handle(GEOM_Function) aRefSh = anObj->GetLastFunction();
00208     if (aRefSh.IsNull()) {
00209       SetErrorCode("NULL tool shape for Partition");
00210       return NULL;
00211     }
00212     aToolsSeq->Append(aRefSh);
00213 
00214     // For Python command
00215     TDF_Tool::Entry(anObj->GetEntry(), anEntry);
00216     if (ind > 1) aToolsDescr += ", ";
00217     aToolsDescr += anEntry;
00218   }
00219   aCI.SetTools(aToolsSeq);
00220 
00221   // Keep Inside
00222   aLen = theKeepIns->Length();
00223   for (ind = 1; ind <= aLen; ind++) {
00224     Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(theKeepIns->Value(ind));
00225     Handle(GEOM_Function) aRefSh = anObj->GetLastFunction();
00226     if (aRefSh.IsNull()) {
00227       SetErrorCode("NULL <keep inside> shape for Partition");
00228       return NULL;
00229     }
00230     aKeepInsSeq->Append(aRefSh);
00231 
00232     // For Python command
00233     TDF_Tool::Entry(anObj->GetEntry(), anEntry);
00234     if (ind > 1) aKeepInsDescr += ", ";
00235     aKeepInsDescr += anEntry;
00236   }
00237   aCI.SetKeepIns(aKeepInsSeq);
00238 
00239   // Remove Inside
00240   aLen = theRemoveIns->Length();
00241   for (ind = 1; ind <= aLen; ind++) {
00242     Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(theRemoveIns->Value(ind));
00243     Handle(GEOM_Function) aRefSh = anObj->GetLastFunction();
00244     if (aRefSh.IsNull()) {
00245       SetErrorCode("NULL <remove inside> shape for Partition");
00246       return NULL;
00247     }
00248     aRemInsSeq->Append(aRefSh);
00249 
00250     // For Python command
00251     TDF_Tool::Entry(anObj->GetEntry(), anEntry);
00252     if (ind > 1) aRemoveInsDescr += ", ";
00253     aRemoveInsDescr += anEntry;
00254   }
00255   aCI.SetRemoveIns(aRemInsSeq);
00256 
00257   // Limit
00258   aCI.SetLimit(theLimit);
00259   aCI.SetKeepNonlimitShapes(theKeepNonlimitShapes);
00260 
00261   // Materials
00262   if (theRemoveWebs) {
00263     if (theMaterials.IsNull()) {
00264       Handle(TColStd_HArray1OfInteger) aMaterials =
00265         new TColStd_HArray1OfInteger (1, aShapesSeq->Length());
00266       aMaterials->Init(0);
00267       aCI.SetMaterials(aMaterials);
00268     } else {
00269       aCI.SetMaterials(theMaterials);
00270     }
00271   }
00272 
00273   //Compute the Partition
00274   try {
00275 #if OCC_VERSION_LARGE > 0x06010000
00276     OCC_CATCH_SIGNALS;
00277 #endif
00278     if (!GetSolver()->ComputeFunction(aFunction)) {
00279       SetErrorCode("Partition driver failed");
00280       return NULL;
00281     }
00282   }
00283   catch (Standard_Failure) {
00284     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
00285     SetErrorCode(aFail->GetMessageString());
00286     return NULL;
00287   }
00288 
00289   //Make a Python command
00290   GEOM::TPythonDump pd (aFunction);
00291   if (thePerformSelfIntersections)
00292     pd << aPartition << " = geompy.MakePartition([";
00293   else
00294     pd << aPartition << " = geompy.MakePartitionNonSelfIntersectedShape([";
00295 
00296   // Shapes, Tools
00297   pd << aShapesDescr.ToCString() << "], [" << aToolsDescr.ToCString() << "], [";
00298   // Keep Ins, Remove Ins
00299   pd << aKeepInsDescr.ToCString() << "], [" << aRemoveInsDescr.ToCString() << "], ";
00300   // Limit, Remove Webs
00301   pd << TopAbs_ShapeEnum(theLimit) << ", " << (int)theRemoveWebs << ", [";
00302   // Materials
00303   if (!theMaterials.IsNull() && theMaterials->Length() > 0) {
00304     int i = theMaterials->Lower();
00305     pd << theMaterials->Value(i);
00306     i++;
00307     for (; i <= theMaterials->Upper(); i++) {
00308       pd << ", " << theMaterials->Value(i);
00309     }
00310   }
00311   pd << "], " << theKeepNonlimitShapes <<")";
00312 
00313   SetErrorCode(OK);
00314   return aPartition;
00315 }
00316 
00317 //=============================================================================
00321 //=============================================================================
00322 Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakeHalfPartition
00323        (Handle(GEOM_Object) theShape, Handle(GEOM_Object) thePlane)
00324 {
00325   SetErrorCode(KO);
00326 
00327   if (theShape.IsNull() || thePlane.IsNull()) return NULL;
00328 
00329   //Add a new Boolean object
00330   Handle(GEOM_Object) aPart = GetEngine()->AddObject(GetDocID(), GEOM_PARTITION);
00331 
00332   //Add a new Partition function
00333   Handle(GEOM_Function) aFunction =
00334     aPart->AddFunction(GEOMImpl_PartitionDriver::GetID(), PARTITION_HALF);
00335   if (aFunction.IsNull()) return NULL;
00336 
00337   //Check if the function is set correctly
00338   if (aFunction->GetDriverGUID() != GEOMImpl_PartitionDriver::GetID()) return NULL;
00339 
00340   GEOMImpl_IPartition aCI (aFunction);
00341 
00342   Handle(GEOM_Function) aRef1 = theShape->GetLastFunction();
00343   Handle(GEOM_Function) aRef2 = thePlane->GetLastFunction();
00344 
00345   if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
00346 
00347   aCI.SetShape(aRef1);
00348   aCI.SetPlane(aRef2);
00349 
00350   //Compute the Partition value
00351   try {
00352 #if OCC_VERSION_LARGE > 0x06010000
00353     OCC_CATCH_SIGNALS;
00354 #endif
00355     if (!GetSolver()->ComputeFunction(aFunction)) {
00356       SetErrorCode("Partition driver failed");
00357       return NULL;
00358     }
00359   }
00360   catch (Standard_Failure) {
00361     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
00362     SetErrorCode(aFail->GetMessageString());
00363     return NULL;
00364   }
00365 
00366   //Make a Python command
00367   GEOM::TPythonDump(aFunction) << aPart << " = geompy.MakeHalfPartition("
00368                                << theShape << ", " << thePlane << ")";
00369 
00370   SetErrorCode(OK);
00371   return aPart;
00372 }