1 // Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
9 // This library is distributed in the hope that it will be useful
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 #include <Standard_Stream.hxx>
23 #include <GEOMImpl_IBooleanOperations.hxx>
25 #include <GEOM_Function.hxx>
26 #include <GEOM_PythonDump.hxx>
28 #include <GEOMImpl_Types.hxx>
30 #include <GEOMImpl_BooleanDriver.hxx>
31 #include <GEOMImpl_IBoolean.hxx>
33 #include <GEOMImpl_PartitionDriver.hxx>
34 #include <GEOMImpl_IPartition.hxx>
36 #include <TDF_Tool.hxx>
38 #include "utilities.h"
40 #include <Standard_Failure.hxx>
41 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
43 //=============================================================================
47 //=============================================================================
48 GEOMImpl_IBooleanOperations::GEOMImpl_IBooleanOperations (GEOM_Engine* theEngine, int theDocID)
49 : GEOM_IOperations(theEngine, theDocID)
51 MESSAGE("GEOMImpl_IBooleanOperations::GEOMImpl_IBooleanOperations");
54 //=============================================================================
58 //=============================================================================
59 GEOMImpl_IBooleanOperations::~GEOMImpl_IBooleanOperations()
61 MESSAGE("GEOMImpl_IBooleanOperations::~GEOMImpl_IBooleanOperations");
65 //=============================================================================
69 //=============================================================================
70 Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakeBoolean (Handle(GEOM_Object) theShape1,
71 Handle(GEOM_Object) theShape2,
72 Standard_Integer theOp)
76 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
78 //Add a new Boolean object
79 Handle(GEOM_Object) aBool = GetEngine()->AddObject(GetDocID(), GEOM_BOOLEAN);
81 //Add a new Boolean function
82 Handle(GEOM_Function) aFunction;
84 aFunction = aBool->AddFunction(GEOMImpl_BooleanDriver::GetID(), BOOLEAN_COMMON);
85 } else if (theOp == 2) {
86 aFunction = aBool->AddFunction(GEOMImpl_BooleanDriver::GetID(), BOOLEAN_CUT);
87 } else if (theOp == 3) {
88 aFunction = aBool->AddFunction(GEOMImpl_BooleanDriver::GetID(), BOOLEAN_FUSE);
89 } else if (theOp == 4) {
90 aFunction = aBool->AddFunction(GEOMImpl_BooleanDriver::GetID(), BOOLEAN_SECTION);
93 if (aFunction.IsNull()) return NULL;
95 //Check if the function is set correctly
96 if (aFunction->GetDriverGUID() != GEOMImpl_BooleanDriver::GetID()) return NULL;
98 GEOMImpl_IBoolean aCI (aFunction);
100 Handle(GEOM_Function) aRef1 = theShape1->GetLastFunction();
101 Handle(GEOM_Function) aRef2 = theShape2->GetLastFunction();
103 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
105 aCI.SetShape1(aRef1);
106 aCI.SetShape2(aRef2);
108 //Compute the Boolean value
110 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
113 if (!GetSolver()->ComputeFunction(aFunction)) {
114 SetErrorCode("Boolean driver failed");
118 catch (Standard_Failure) {
119 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
120 SetErrorCode(aFail->GetMessageString());
124 //Make a Python command
125 GEOM::TPythonDump pd (aFunction);
127 if (theOp == 1) pd << " = geompy.MakeCommon(";
128 else if (theOp == 2) pd << " = geompy.MakeCut(";
129 else if (theOp == 3) pd << " = geompy.MakeFuse(";
130 else if (theOp == 4) pd << " = geompy.MakeSection(";
132 pd << theShape1 << ", " << theShape2 << ")";
138 //=============================================================================
142 //=============================================================================
143 Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakePartition
144 (const Handle(TColStd_HSequenceOfTransient)& theShapes,
145 const Handle(TColStd_HSequenceOfTransient)& theTools,
146 const Handle(TColStd_HSequenceOfTransient)& theKeepIns,
147 const Handle(TColStd_HSequenceOfTransient)& theRemoveIns,
148 const Standard_Integer theLimit,
149 const Standard_Boolean theRemoveWebs,
150 const Handle(TColStd_HArray1OfInteger)& theMaterials,
151 const Standard_Integer theKeepNonlimitShapes,
152 const Standard_Boolean thePerformSelfIntersections)
156 //Add a new Partition object
157 Handle(GEOM_Object) aPartition = GetEngine()->AddObject(GetDocID(), GEOM_PARTITION);
159 //Add a new Partition function
160 Handle(GEOM_Function) aFunction;
161 if (thePerformSelfIntersections)
162 aFunction = aPartition->AddFunction(GEOMImpl_PartitionDriver::GetID(), PARTITION_PARTITION);
164 aFunction = aPartition->AddFunction(GEOMImpl_PartitionDriver::GetID(), PARTITION_NO_SELF_INTERSECTIONS);
165 if (aFunction.IsNull()) return NULL;
167 //Check if the function is set correctly
168 if (aFunction->GetDriverGUID() != GEOMImpl_PartitionDriver::GetID()) return NULL;
170 GEOMImpl_IPartition aCI (aFunction);
172 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
173 Handle(TColStd_HSequenceOfTransient) aToolsSeq = new TColStd_HSequenceOfTransient;
174 Handle(TColStd_HSequenceOfTransient) aKeepInsSeq = new TColStd_HSequenceOfTransient;
175 Handle(TColStd_HSequenceOfTransient) aRemInsSeq = new TColStd_HSequenceOfTransient;
177 Standard_Integer ind, aLen;
178 TCollection_AsciiString anEntry;
179 TCollection_AsciiString aShapesDescr, aToolsDescr, aKeepInsDescr, aRemoveInsDescr;
182 aLen = theShapes->Length();
183 for (ind = 1; ind <= aLen; ind++) {
184 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(theShapes->Value(ind));
185 Handle(GEOM_Function) aRefSh = anObj->GetLastFunction();
186 if (aRefSh.IsNull()) {
187 SetErrorCode("NULL shape for Partition");
190 aShapesSeq->Append(aRefSh);
192 // For Python command
193 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
194 if (ind > 1) aShapesDescr += ", ";
195 aShapesDescr += anEntry;
197 aCI.SetShapes(aShapesSeq);
200 aLen = theTools->Length();
201 for (ind = 1; ind <= aLen; ind++) {
202 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(theTools->Value(ind));
203 Handle(GEOM_Function) aRefSh = anObj->GetLastFunction();
204 if (aRefSh.IsNull()) {
205 SetErrorCode("NULL tool shape for Partition");
208 aToolsSeq->Append(aRefSh);
210 // For Python command
211 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
212 if (ind > 1) aToolsDescr += ", ";
213 aToolsDescr += anEntry;
215 aCI.SetTools(aToolsSeq);
218 aLen = theKeepIns->Length();
219 for (ind = 1; ind <= aLen; ind++) {
220 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(theKeepIns->Value(ind));
221 Handle(GEOM_Function) aRefSh = anObj->GetLastFunction();
222 if (aRefSh.IsNull()) {
223 SetErrorCode("NULL <keep inside> shape for Partition");
226 aKeepInsSeq->Append(aRefSh);
228 // For Python command
229 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
230 if (ind > 1) aKeepInsDescr += ", ";
231 aKeepInsDescr += anEntry;
233 aCI.SetKeepIns(aKeepInsSeq);
236 aLen = theRemoveIns->Length();
237 for (ind = 1; ind <= aLen; ind++) {
238 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(theRemoveIns->Value(ind));
239 Handle(GEOM_Function) aRefSh = anObj->GetLastFunction();
240 if (aRefSh.IsNull()) {
241 SetErrorCode("NULL <remove inside> shape for Partition");
244 aRemInsSeq->Append(aRefSh);
246 // For Python command
247 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
248 if (ind > 1) aRemoveInsDescr += ", ";
249 aRemoveInsDescr += anEntry;
251 aCI.SetRemoveIns(aRemInsSeq);
254 aCI.SetLimit(theLimit);
255 aCI.SetKeepNonlimitShapes(theKeepNonlimitShapes);
259 if (theMaterials.IsNull()) {
260 Handle(TColStd_HArray1OfInteger) aMaterials =
261 new TColStd_HArray1OfInteger (1, aShapesSeq->Length());
263 aCI.SetMaterials(aMaterials);
265 aCI.SetMaterials(theMaterials);
269 //Compute the Partition
271 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
274 if (!GetSolver()->ComputeFunction(aFunction)) {
275 SetErrorCode("Partition driver failed");
279 catch (Standard_Failure) {
280 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
281 SetErrorCode(aFail->GetMessageString());
285 //Make a Python command
286 GEOM::TPythonDump pd (aFunction);
287 if (thePerformSelfIntersections)
288 pd << aPartition << " = geompy.MakePartition([";
290 pd << aPartition << " = geompy.MakePartitionNonSelfIntersectedShape([";
293 pd << aShapesDescr.ToCString() << "], [" << aToolsDescr.ToCString() << "], [";
294 // Keep Ins, Remove Ins
295 pd << aKeepInsDescr.ToCString() << "], [" << aRemoveInsDescr.ToCString() << "], ";
296 // Limit, Remove Webs
297 pd << TopAbs_ShapeEnum(theLimit) << ", " << (int)theRemoveWebs << ", [";
299 if (!theMaterials.IsNull() && theMaterials->Length() > 0) {
300 int i = theMaterials->Lower();
301 pd << theMaterials->Value(i);
303 for (; i <= theMaterials->Upper(); i++) {
304 pd << ", " << theMaterials->Value(i);
307 pd << "], " << theKeepNonlimitShapes <<")";
313 //=============================================================================
317 //=============================================================================
318 Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakeHalfPartition
319 (Handle(GEOM_Object) theShape, Handle(GEOM_Object) thePlane)
323 if (theShape.IsNull() || thePlane.IsNull()) return NULL;
325 //Add a new Boolean object
326 Handle(GEOM_Object) aPart = GetEngine()->AddObject(GetDocID(), GEOM_PARTITION);
328 //Add a new Partition function
329 Handle(GEOM_Function) aFunction =
330 aPart->AddFunction(GEOMImpl_PartitionDriver::GetID(), PARTITION_HALF);
331 if (aFunction.IsNull()) return NULL;
333 //Check if the function is set correctly
334 if (aFunction->GetDriverGUID() != GEOMImpl_PartitionDriver::GetID()) return NULL;
336 GEOMImpl_IPartition aCI (aFunction);
338 Handle(GEOM_Function) aRef1 = theShape->GetLastFunction();
339 Handle(GEOM_Function) aRef2 = thePlane->GetLastFunction();
341 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
346 //Compute the Partition value
348 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
351 if (!GetSolver()->ComputeFunction(aFunction)) {
352 SetErrorCode("Partition driver failed");
356 catch (Standard_Failure) {
357 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
358 SetErrorCode(aFail->GetMessageString());
362 //Make a Python command
363 GEOM::TPythonDump(aFunction) << aPart << " = geompy.MakeHalfPartition("
364 << theShape << ", " << thePlane << ")";