1 // Copyright (C) 2007-2010 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.
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
23 #include <Standard_Stream.hxx>
25 #include <GEOMImpl_IBooleanOperations.hxx>
27 #include <GEOM_Function.hxx>
28 #include <GEOM_PythonDump.hxx>
30 #include <GEOMImpl_Types.hxx>
32 #include <GEOMImpl_BooleanDriver.hxx>
33 #include <GEOMImpl_IBoolean.hxx>
35 #include <GEOMImpl_PartitionDriver.hxx>
36 #include <GEOMImpl_IPartition.hxx>
38 #include <TDF_Tool.hxx>
40 #include "utilities.h"
42 #include <Standard_Failure.hxx>
43 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
45 //=============================================================================
49 //=============================================================================
50 GEOMImpl_IBooleanOperations::GEOMImpl_IBooleanOperations (GEOM_Engine* theEngine, int theDocID)
51 : GEOM_IOperations(theEngine, theDocID)
53 MESSAGE("GEOMImpl_IBooleanOperations::GEOMImpl_IBooleanOperations");
56 //=============================================================================
60 //=============================================================================
61 GEOMImpl_IBooleanOperations::~GEOMImpl_IBooleanOperations()
63 MESSAGE("GEOMImpl_IBooleanOperations::~GEOMImpl_IBooleanOperations");
67 //=============================================================================
71 //=============================================================================
72 Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakeBoolean (Handle(GEOM_Object) theShape1,
73 Handle(GEOM_Object) theShape2,
74 Standard_Integer theOp)
78 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
80 //Add a new Boolean object
81 Handle(GEOM_Object) aBool = GetEngine()->AddObject(GetDocID(), GEOM_BOOLEAN);
83 //Add a new Boolean function
84 Handle(GEOM_Function) aFunction;
86 aFunction = aBool->AddFunction(GEOMImpl_BooleanDriver::GetID(), BOOLEAN_COMMON);
87 } else if (theOp == 2) {
88 aFunction = aBool->AddFunction(GEOMImpl_BooleanDriver::GetID(), BOOLEAN_CUT);
89 } else if (theOp == 3) {
90 aFunction = aBool->AddFunction(GEOMImpl_BooleanDriver::GetID(), BOOLEAN_FUSE);
91 } else if (theOp == 4) {
92 aFunction = aBool->AddFunction(GEOMImpl_BooleanDriver::GetID(), BOOLEAN_SECTION);
95 if (aFunction.IsNull()) return NULL;
97 //Check if the function is set correctly
98 if (aFunction->GetDriverGUID() != GEOMImpl_BooleanDriver::GetID()) return NULL;
100 GEOMImpl_IBoolean aCI (aFunction);
102 Handle(GEOM_Function) aRef1 = theShape1->GetLastFunction();
103 Handle(GEOM_Function) aRef2 = theShape2->GetLastFunction();
105 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
107 aCI.SetShape1(aRef1);
108 aCI.SetShape2(aRef2);
110 //Compute the Boolean value
112 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
115 if (!GetSolver()->ComputeFunction(aFunction)) {
116 SetErrorCode("Boolean driver failed");
120 catch (Standard_Failure) {
121 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
122 SetErrorCode(aFail->GetMessageString());
126 //Make a Python command
127 GEOM::TPythonDump pd (aFunction);
129 if (theOp == 1) pd << " = geompy.MakeCommon(";
130 else if (theOp == 2) pd << " = geompy.MakeCut(";
131 else if (theOp == 3) pd << " = geompy.MakeFuse(";
132 else if (theOp == 4) pd << " = geompy.MakeSection(";
134 pd << theShape1 << ", " << theShape2 << ")";
140 //=============================================================================
144 //=============================================================================
145 Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakePartition
146 (const Handle(TColStd_HSequenceOfTransient)& theShapes,
147 const Handle(TColStd_HSequenceOfTransient)& theTools,
148 const Handle(TColStd_HSequenceOfTransient)& theKeepIns,
149 const Handle(TColStd_HSequenceOfTransient)& theRemoveIns,
150 const Standard_Integer theLimit,
151 const Standard_Boolean theRemoveWebs,
152 const Handle(TColStd_HArray1OfInteger)& theMaterials,
153 const Standard_Integer theKeepNonlimitShapes,
154 const Standard_Boolean thePerformSelfIntersections)
158 //Add a new Partition object
159 Handle(GEOM_Object) aPartition = GetEngine()->AddObject(GetDocID(), GEOM_PARTITION);
161 //Add a new Partition function
162 Handle(GEOM_Function) aFunction;
163 if (thePerformSelfIntersections)
164 aFunction = aPartition->AddFunction(GEOMImpl_PartitionDriver::GetID(), PARTITION_PARTITION);
166 aFunction = aPartition->AddFunction(GEOMImpl_PartitionDriver::GetID(), PARTITION_NO_SELF_INTERSECTIONS);
167 if (aFunction.IsNull()) return NULL;
169 //Check if the function is set correctly
170 if (aFunction->GetDriverGUID() != GEOMImpl_PartitionDriver::GetID()) return NULL;
172 GEOMImpl_IPartition aCI (aFunction);
174 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
175 Handle(TColStd_HSequenceOfTransient) aToolsSeq = new TColStd_HSequenceOfTransient;
176 Handle(TColStd_HSequenceOfTransient) aKeepInsSeq = new TColStd_HSequenceOfTransient;
177 Handle(TColStd_HSequenceOfTransient) aRemInsSeq = new TColStd_HSequenceOfTransient;
179 Standard_Integer ind, aLen;
180 TCollection_AsciiString anEntry;
181 TCollection_AsciiString aShapesDescr, aToolsDescr, aKeepInsDescr, aRemoveInsDescr;
184 aLen = theShapes->Length();
185 for (ind = 1; ind <= aLen; ind++) {
186 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(theShapes->Value(ind));
187 Handle(GEOM_Function) aRefSh = anObj->GetLastFunction();
188 if (aRefSh.IsNull()) {
189 SetErrorCode("NULL shape for Partition");
192 aShapesSeq->Append(aRefSh);
194 // For Python command
195 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
196 if (ind > 1) aShapesDescr += ", ";
197 aShapesDescr += anEntry;
199 aCI.SetShapes(aShapesSeq);
202 aLen = theTools->Length();
203 for (ind = 1; ind <= aLen; ind++) {
204 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(theTools->Value(ind));
205 Handle(GEOM_Function) aRefSh = anObj->GetLastFunction();
206 if (aRefSh.IsNull()) {
207 SetErrorCode("NULL tool shape for Partition");
210 aToolsSeq->Append(aRefSh);
212 // For Python command
213 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
214 if (ind > 1) aToolsDescr += ", ";
215 aToolsDescr += anEntry;
217 aCI.SetTools(aToolsSeq);
220 aLen = theKeepIns->Length();
221 for (ind = 1; ind <= aLen; ind++) {
222 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(theKeepIns->Value(ind));
223 Handle(GEOM_Function) aRefSh = anObj->GetLastFunction();
224 if (aRefSh.IsNull()) {
225 SetErrorCode("NULL <keep inside> shape for Partition");
228 aKeepInsSeq->Append(aRefSh);
230 // For Python command
231 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
232 if (ind > 1) aKeepInsDescr += ", ";
233 aKeepInsDescr += anEntry;
235 aCI.SetKeepIns(aKeepInsSeq);
238 aLen = theRemoveIns->Length();
239 for (ind = 1; ind <= aLen; ind++) {
240 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(theRemoveIns->Value(ind));
241 Handle(GEOM_Function) aRefSh = anObj->GetLastFunction();
242 if (aRefSh.IsNull()) {
243 SetErrorCode("NULL <remove inside> shape for Partition");
246 aRemInsSeq->Append(aRefSh);
248 // For Python command
249 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
250 if (ind > 1) aRemoveInsDescr += ", ";
251 aRemoveInsDescr += anEntry;
253 aCI.SetRemoveIns(aRemInsSeq);
256 aCI.SetLimit(theLimit);
257 aCI.SetKeepNonlimitShapes(theKeepNonlimitShapes);
261 if (theMaterials.IsNull()) {
262 Handle(TColStd_HArray1OfInteger) aMaterials =
263 new TColStd_HArray1OfInteger (1, aShapesSeq->Length());
265 aCI.SetMaterials(aMaterials);
267 aCI.SetMaterials(theMaterials);
271 //Compute the Partition
273 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
276 if (!GetSolver()->ComputeFunction(aFunction)) {
277 SetErrorCode("Partition driver failed");
281 catch (Standard_Failure) {
282 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
283 SetErrorCode(aFail->GetMessageString());
287 //Make a Python command
288 GEOM::TPythonDump pd (aFunction);
289 if (thePerformSelfIntersections)
290 pd << aPartition << " = geompy.MakePartition([";
292 pd << aPartition << " = geompy.MakePartitionNonSelfIntersectedShape([";
295 pd << aShapesDescr.ToCString() << "], [" << aToolsDescr.ToCString() << "], [";
296 // Keep Ins, Remove Ins
297 pd << aKeepInsDescr.ToCString() << "], [" << aRemoveInsDescr.ToCString() << "], ";
298 // Limit, Remove Webs
299 pd << TopAbs_ShapeEnum(theLimit) << ", " << (int)theRemoveWebs << ", [";
301 if (!theMaterials.IsNull() && theMaterials->Length() > 0) {
302 int i = theMaterials->Lower();
303 pd << theMaterials->Value(i);
305 for (; i <= theMaterials->Upper(); i++) {
306 pd << ", " << theMaterials->Value(i);
309 pd << "], " << theKeepNonlimitShapes <<")";
315 //=============================================================================
319 //=============================================================================
320 Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakeHalfPartition
321 (Handle(GEOM_Object) theShape, Handle(GEOM_Object) thePlane)
325 if (theShape.IsNull() || thePlane.IsNull()) return NULL;
327 //Add a new Boolean object
328 Handle(GEOM_Object) aPart = GetEngine()->AddObject(GetDocID(), GEOM_PARTITION);
330 //Add a new Partition function
331 Handle(GEOM_Function) aFunction =
332 aPart->AddFunction(GEOMImpl_PartitionDriver::GetID(), PARTITION_HALF);
333 if (aFunction.IsNull()) return NULL;
335 //Check if the function is set correctly
336 if (aFunction->GetDriverGUID() != GEOMImpl_PartitionDriver::GetID()) return NULL;
338 GEOMImpl_IPartition aCI (aFunction);
340 Handle(GEOM_Function) aRef1 = theShape->GetLastFunction();
341 Handle(GEOM_Function) aRef2 = thePlane->GetLastFunction();
343 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
348 //Compute the Partition value
350 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
353 if (!GetSolver()->ComputeFunction(aFunction)) {
354 SetErrorCode("Partition driver failed");
358 catch (Standard_Failure) {
359 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
360 SetErrorCode(aFail->GetMessageString());
364 //Make a Python command
365 GEOM::TPythonDump(aFunction) << aPart << " = geompy.MakeHalfPartition("
366 << theShape << ", " << thePlane << ")";