1 // Copyright (C) 2007-2008 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
22 #include <Standard_Stream.hxx>
24 #include <GEOMImpl_IBooleanOperations.hxx>
26 #include <GEOM_Function.hxx>
27 #include <GEOM_PythonDump.hxx>
29 #include <GEOMImpl_Types.hxx>
31 #include <GEOMImpl_BooleanDriver.hxx>
32 #include <GEOMImpl_IBoolean.hxx>
34 #include <GEOMImpl_PartitionDriver.hxx>
35 #include <GEOMImpl_IPartition.hxx>
37 #include <TDF_Tool.hxx>
39 #include "utilities.h"
41 #include <Standard_Failure.hxx>
42 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
44 //=============================================================================
48 //=============================================================================
49 GEOMImpl_IBooleanOperations::GEOMImpl_IBooleanOperations (GEOM_Engine* theEngine, int theDocID)
50 : GEOM_IOperations(theEngine, theDocID)
52 MESSAGE("GEOMImpl_IBooleanOperations::GEOMImpl_IBooleanOperations");
55 //=============================================================================
59 //=============================================================================
60 GEOMImpl_IBooleanOperations::~GEOMImpl_IBooleanOperations()
62 MESSAGE("GEOMImpl_IBooleanOperations::~GEOMImpl_IBooleanOperations");
66 //=============================================================================
70 //=============================================================================
71 Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakeBoolean (Handle(GEOM_Object) theShape1,
72 Handle(GEOM_Object) theShape2,
73 Standard_Integer theOp)
77 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
79 //Add a new Boolean object
80 Handle(GEOM_Object) aBool = GetEngine()->AddObject(GetDocID(), GEOM_BOOLEAN);
82 //Add a new Boolean function
83 Handle(GEOM_Function) aFunction;
85 aFunction = aBool->AddFunction(GEOMImpl_BooleanDriver::GetID(), BOOLEAN_COMMON);
86 } else if (theOp == 2) {
87 aFunction = aBool->AddFunction(GEOMImpl_BooleanDriver::GetID(), BOOLEAN_CUT);
88 } else if (theOp == 3) {
89 aFunction = aBool->AddFunction(GEOMImpl_BooleanDriver::GetID(), BOOLEAN_FUSE);
90 } else if (theOp == 4) {
91 aFunction = aBool->AddFunction(GEOMImpl_BooleanDriver::GetID(), BOOLEAN_SECTION);
94 if (aFunction.IsNull()) return NULL;
96 //Check if the function is set correctly
97 if (aFunction->GetDriverGUID() != GEOMImpl_BooleanDriver::GetID()) return NULL;
99 GEOMImpl_IBoolean aCI (aFunction);
101 Handle(GEOM_Function) aRef1 = theShape1->GetLastFunction();
102 Handle(GEOM_Function) aRef2 = theShape2->GetLastFunction();
104 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
106 aCI.SetShape1(aRef1);
107 aCI.SetShape2(aRef2);
109 //Compute the Boolean value
111 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
114 if (!GetSolver()->ComputeFunction(aFunction)) {
115 SetErrorCode("Boolean driver failed");
119 catch (Standard_Failure) {
120 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
121 SetErrorCode(aFail->GetMessageString());
125 //Make a Python command
126 GEOM::TPythonDump pd (aFunction);
128 if (theOp == 1) pd << " = geompy.MakeCommon(";
129 else if (theOp == 2) pd << " = geompy.MakeCut(";
130 else if (theOp == 3) pd << " = geompy.MakeFuse(";
131 else if (theOp == 4) pd << " = geompy.MakeSection(";
133 pd << theShape1 << ", " << theShape2 << ")";
139 //=============================================================================
143 //=============================================================================
144 Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakePartition
145 (const Handle(TColStd_HSequenceOfTransient)& theShapes,
146 const Handle(TColStd_HSequenceOfTransient)& theTools,
147 const Handle(TColStd_HSequenceOfTransient)& theKeepIns,
148 const Handle(TColStd_HSequenceOfTransient)& theRemoveIns,
149 const Standard_Integer theLimit,
150 const Standard_Boolean theRemoveWebs,
151 const Handle(TColStd_HArray1OfInteger)& theMaterials,
152 const Standard_Integer theKeepNonlimitShapes,
153 const Standard_Boolean thePerformSelfIntersections)
157 //Add a new Partition object
158 Handle(GEOM_Object) aPartition = GetEngine()->AddObject(GetDocID(), GEOM_PARTITION);
160 //Add a new Partition function
161 Handle(GEOM_Function) aFunction;
162 if (thePerformSelfIntersections)
163 aFunction = aPartition->AddFunction(GEOMImpl_PartitionDriver::GetID(), PARTITION_PARTITION);
165 aFunction = aPartition->AddFunction(GEOMImpl_PartitionDriver::GetID(), PARTITION_NO_SELF_INTERSECTIONS);
166 if (aFunction.IsNull()) return NULL;
168 //Check if the function is set correctly
169 if (aFunction->GetDriverGUID() != GEOMImpl_PartitionDriver::GetID()) return NULL;
171 GEOMImpl_IPartition aCI (aFunction);
173 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
174 Handle(TColStd_HSequenceOfTransient) aToolsSeq = new TColStd_HSequenceOfTransient;
175 Handle(TColStd_HSequenceOfTransient) aKeepInsSeq = new TColStd_HSequenceOfTransient;
176 Handle(TColStd_HSequenceOfTransient) aRemInsSeq = new TColStd_HSequenceOfTransient;
178 Standard_Integer ind, aLen;
179 TCollection_AsciiString anEntry;
180 TCollection_AsciiString aShapesDescr, aToolsDescr, aKeepInsDescr, aRemoveInsDescr;
183 aLen = theShapes->Length();
184 for (ind = 1; ind <= aLen; ind++) {
185 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(theShapes->Value(ind));
186 Handle(GEOM_Function) aRefSh = anObj->GetLastFunction();
187 if (aRefSh.IsNull()) {
188 SetErrorCode("NULL shape for Partition");
191 aShapesSeq->Append(aRefSh);
193 // For Python command
194 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
195 if (ind > 1) aShapesDescr += ", ";
196 aShapesDescr += anEntry;
198 aCI.SetShapes(aShapesSeq);
201 aLen = theTools->Length();
202 for (ind = 1; ind <= aLen; ind++) {
203 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(theTools->Value(ind));
204 Handle(GEOM_Function) aRefSh = anObj->GetLastFunction();
205 if (aRefSh.IsNull()) {
206 SetErrorCode("NULL tool shape for Partition");
209 aToolsSeq->Append(aRefSh);
211 // For Python command
212 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
213 if (ind > 1) aToolsDescr += ", ";
214 aToolsDescr += anEntry;
216 aCI.SetTools(aToolsSeq);
219 aLen = theKeepIns->Length();
220 for (ind = 1; ind <= aLen; ind++) {
221 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(theKeepIns->Value(ind));
222 Handle(GEOM_Function) aRefSh = anObj->GetLastFunction();
223 if (aRefSh.IsNull()) {
224 SetErrorCode("NULL <keep inside> shape for Partition");
227 aKeepInsSeq->Append(aRefSh);
229 // For Python command
230 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
231 if (ind > 1) aKeepInsDescr += ", ";
232 aKeepInsDescr += anEntry;
234 aCI.SetKeepIns(aKeepInsSeq);
237 aLen = theRemoveIns->Length();
238 for (ind = 1; ind <= aLen; ind++) {
239 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(theRemoveIns->Value(ind));
240 Handle(GEOM_Function) aRefSh = anObj->GetLastFunction();
241 if (aRefSh.IsNull()) {
242 SetErrorCode("NULL <remove inside> shape for Partition");
245 aRemInsSeq->Append(aRefSh);
247 // For Python command
248 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
249 if (ind > 1) aRemoveInsDescr += ", ";
250 aRemoveInsDescr += anEntry;
252 aCI.SetRemoveIns(aRemInsSeq);
255 aCI.SetLimit(theLimit);
256 aCI.SetKeepNonlimitShapes(theKeepNonlimitShapes);
260 if (theMaterials.IsNull()) {
261 Handle(TColStd_HArray1OfInteger) aMaterials =
262 new TColStd_HArray1OfInteger (1, aShapesSeq->Length());
264 aCI.SetMaterials(aMaterials);
266 aCI.SetMaterials(theMaterials);
270 //Compute the Partition
272 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
275 if (!GetSolver()->ComputeFunction(aFunction)) {
276 SetErrorCode("Partition driver failed");
280 catch (Standard_Failure) {
281 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
282 SetErrorCode(aFail->GetMessageString());
286 //Make a Python command
287 GEOM::TPythonDump pd (aFunction);
288 if (thePerformSelfIntersections)
289 pd << aPartition << " = geompy.MakePartition([";
291 pd << aPartition << " = geompy.MakePartitionNonSelfIntersectedShape([";
294 pd << aShapesDescr.ToCString() << "], [" << aToolsDescr.ToCString() << "], [";
295 // Keep Ins, Remove Ins
296 pd << aKeepInsDescr.ToCString() << "], [" << aRemoveInsDescr.ToCString() << "], ";
297 // Limit, Remove Webs
298 pd << TopAbs_ShapeEnum(theLimit) << ", " << (int)theRemoveWebs << ", [";
300 if (!theMaterials.IsNull() && theMaterials->Length() > 0) {
301 int i = theMaterials->Lower();
302 pd << theMaterials->Value(i);
304 for (; i <= theMaterials->Upper(); i++) {
305 pd << ", " << theMaterials->Value(i);
308 pd << "], " << theKeepNonlimitShapes <<")";
314 //=============================================================================
318 //=============================================================================
319 Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakeHalfPartition
320 (Handle(GEOM_Object) theShape, Handle(GEOM_Object) thePlane)
324 if (theShape.IsNull() || thePlane.IsNull()) return NULL;
326 //Add a new Boolean object
327 Handle(GEOM_Object) aPart = GetEngine()->AddObject(GetDocID(), GEOM_PARTITION);
329 //Add a new Partition function
330 Handle(GEOM_Function) aFunction =
331 aPart->AddFunction(GEOMImpl_PartitionDriver::GetID(), PARTITION_HALF);
332 if (aFunction.IsNull()) return NULL;
334 //Check if the function is set correctly
335 if (aFunction->GetDriverGUID() != GEOMImpl_PartitionDriver::GetID()) return NULL;
337 GEOMImpl_IPartition aCI (aFunction);
339 Handle(GEOM_Function) aRef1 = theShape->GetLastFunction();
340 Handle(GEOM_Function) aRef2 = thePlane->GetLastFunction();
342 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
347 //Compute the Partition value
349 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
352 if (!GetSolver()->ComputeFunction(aFunction)) {
353 SetErrorCode("Partition driver failed");
357 catch (Standard_Failure) {
358 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
359 SetErrorCode(aFail->GetMessageString());
363 //Make a Python command
364 GEOM::TPythonDump(aFunction) << aPart << " = geompy.MakeHalfPartition("
365 << theShape << ", " << thePlane << ")";