1 // Copyright (C) 2007-2013 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_PartitionDriver.hxx>
26 #include <GEOMImpl_IPartition.hxx>
27 #include <GEOMImpl_Types.hxx>
29 #include <GEOM_Object.hxx>
30 #include <GEOM_Function.hxx>
32 #include <GEOMAlgo_Splitter.hxx>
34 #include <TDataStd_IntegerArray.hxx>
35 #include <TNaming_CopyShape.hxx>
37 //#include <BRepBuilderAPI_Copy.hxx>
38 #include <BRep_Tool.hxx>
39 #include <BRepAlgo.hxx>
40 #include <BRepTools.hxx>
45 #include <TopoDS_Shape.hxx>
46 #include <TopoDS_Vertex.hxx>
47 #include <TopoDS_Wire.hxx>
48 #include <TopoDS_Iterator.hxx>
49 #include <TopTools_MapOfShape.hxx>
50 #include <TopTools_IndexedMapOfShape.hxx>
51 #include <TopTools_ListIteratorOfListOfShape.hxx>
52 #include <TopTools_DataMapOfShapeShape.hxx>
54 #include <ShapeFix_ShapeTolerance.hxx>
55 #include <ShapeFix_Shape.hxx>
57 #include <TColStd_IndexedDataMapOfTransientTransient.hxx>
58 #include <TColStd_ListIteratorOfListOfInteger.hxx>
59 #include <TColStd_ListOfInteger.hxx>
60 #include <Standard_NullObject.hxx>
61 #include <Precision.hxx>
63 #include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
64 #include <BOPCol_ListOfShape.hxx>
66 //=======================================================================
69 //=======================================================================
70 const Standard_GUID& GEOMImpl_PartitionDriver::GetID()
72 static Standard_GUID aPartitionDriver("FF1BBB22-5D14-4df2-980B-3A668264EA16");
73 return aPartitionDriver;
77 //=======================================================================
78 //function : GEOMImpl_PartitionDriver
80 //=======================================================================
81 GEOMImpl_PartitionDriver::GEOMImpl_PartitionDriver()
85 //=======================================================================
86 //function : SimplifyCompound
88 //=======================================================================
89 static void PrepareShapes (const TopoDS_Shape& theShape,
90 Standard_Integer theType,
91 TopTools_ListOfShape& theSimpleList)
93 if (theType == PARTITION_NO_SELF_INTERSECTIONS ||
94 theShape.ShapeType() != TopAbs_COMPOUND) {
95 theSimpleList.Append(theShape);
99 // explode compound on simple shapes to allow their intersections
100 TopoDS_Iterator It (theShape, Standard_True, Standard_True);
101 TopTools_MapOfShape mapShape;
102 for (; It.More(); It.Next()) {
103 if (mapShape.Add(It.Value())) {
104 TopoDS_Shape curSh = It.Value();
105 PrepareShapes(curSh, theType, theSimpleList);
110 //=======================================================================
113 //=======================================================================
114 Standard_Integer GEOMImpl_PartitionDriver::Execute(TFunction_Logbook& log) const
116 if (Label().IsNull()) return 0;
117 Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
119 GEOMImpl_IPartition aCI (aFunction);
120 Standard_Integer aType = aFunction->GetType();
123 GEOMAlgo_Splitter PS;
125 TopTools_DataMapOfShapeShape aCopyMap;
126 TColStd_IndexedDataMapOfTransientTransient aMapTShapes;
128 if (aType == PARTITION_PARTITION || aType == PARTITION_NO_SELF_INTERSECTIONS)
130 Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes();
131 Handle(TColStd_HSequenceOfTransient) aTools = aCI.GetTools();
132 Handle(TColStd_HSequenceOfTransient) aKeepIns = aCI.GetKeepIns();
133 Handle(TColStd_HSequenceOfTransient) aRemIns = aCI.GetRemoveIns();
134 Handle(TColStd_HArray1OfInteger) aMaterials = aCI.GetMaterials();
135 //skl Standard_Boolean DoRemoveWebs = !aMaterials.IsNull();
138 //unsigned int ind, nbshapes = 0;
139 //nbshapes += aShapes->Length() + aTools->Length();
140 //nbshapes += aKeepIns->Length() + aRemIns->Length();
141 //TopTools_MapOfShape ShapesMap(nbshapes), ToolsMap(nbshapes);
142 TopTools_MapOfShape ShapesMap, ToolsMap;
144 // add object shapes that are in ListShapes;
145 for (ind = 1; ind <= aShapes->Length(); ind++) {
146 Handle(GEOM_Function) aRefShape = Handle(GEOM_Function)::DownCast(aShapes->Value(ind));
147 TopoDS_Shape aShape_i = aRefShape->GetValue();
148 if (aShape_i.IsNull()) {
149 Standard_NullObject::Raise("In Partition a shape is null");
152 TopoDS_Shape aShape_i_copy;
153 TNaming_CopyShape::CopyTool(aShape_i, aMapTShapes, aShape_i_copy);
155 // fill aCopyMap for history
156 TopTools_IndexedMapOfShape aShape_i_inds;
157 TopTools_IndexedMapOfShape aShape_i_copy_inds;
158 TopExp::MapShapes(aShape_i, aShape_i_inds);
159 TopExp::MapShapes(aShape_i_copy, aShape_i_copy_inds);
160 Standard_Integer nbInds = aShape_i_inds.Extent();
161 for (Standard_Integer ie = 1; ie <= nbInds; ie++) {
162 aCopyMap.Bind(aShape_i_inds.FindKey(ie), aShape_i_copy_inds.FindKey(ie));
165 TopTools_ListOfShape aSimpleShapes;
166 //PrepareShapes(aShape_i, aType, aSimpleShapes);
167 PrepareShapes(aShape_i_copy, aType, aSimpleShapes);
168 TopTools_ListIteratorOfListOfShape aSimpleIter (aSimpleShapes);
169 for (; aSimpleIter.More(); aSimpleIter.Next()) {
170 const TopoDS_Shape& aSimpleSh = aSimpleIter.Value();
171 if (ShapesMap.Add(aSimpleSh)) {
172 PS.AddArgument(aSimpleSh);
173 //skl if (DoRemoveWebs) {
174 //skl if (aMaterials->Length() >= ind)
175 //skl PS.SetMaterial(aSimpleSh, aMaterials->Value(ind));
181 // add tool shapes that are in ListTools and not in ListShapes;
182 for (ind = 1; ind <= aTools->Length(); ind++) {
183 Handle(GEOM_Function) aRefShape = Handle(GEOM_Function)::DownCast(aTools->Value(ind));
184 TopoDS_Shape aShape_i = aRefShape->GetValue();
185 if (aShape_i.IsNull()) {
186 Standard_NullObject::Raise("In Partition a tool shape is null");
189 //BRepBuilderAPI_Copy aCopyTool (aShape_i);
190 TopoDS_Shape aShape_i_copy;
191 TNaming_CopyShape::CopyTool(aShape_i, aMapTShapes, aShape_i_copy);
192 //if (aCopyTool.IsDone())
193 // aShape_i_copy = aCopyTool.Shape();
195 // Standard_NullObject::Raise("Bad shape detected");
197 // fill aCopyMap for history
198 TopTools_IndexedMapOfShape aShape_i_inds;
199 TopTools_IndexedMapOfShape aShape_i_copy_inds;
200 TopExp::MapShapes(aShape_i, aShape_i_inds);
201 TopExp::MapShapes(aShape_i_copy, aShape_i_copy_inds);
202 Standard_Integer nbInds = aShape_i_inds.Extent();
203 for (Standard_Integer ie = 1; ie <= nbInds; ie++) {
204 aCopyMap.Bind(aShape_i_inds.FindKey(ie), aShape_i_copy_inds.FindKey(ie));
207 TopTools_ListOfShape aSimpleShapes;
208 //PrepareShapes(aShape_i, aType, aSimpleShapes);
209 PrepareShapes(aShape_i_copy, aType, aSimpleShapes);
210 TopTools_ListIteratorOfListOfShape aSimpleIter (aSimpleShapes);
211 for (; aSimpleIter.More(); aSimpleIter.Next()) {
212 const TopoDS_Shape& aSimpleSh = aSimpleIter.Value();
213 if (!ShapesMap.Contains(aSimpleSh) && ToolsMap.Add(aSimpleSh)) {
214 PS.AddTool(aSimpleSh);
219 // add shapes that are in ListKeepInside, as object shapes;
220 for (ind = 1; ind <= aKeepIns->Length(); ind++) {
221 Handle(GEOM_Function) aRefShape = Handle(GEOM_Function)::DownCast(aKeepIns->Value(ind));
222 TopoDS_Shape aShape_i = aRefShape->GetValue();
223 if (aShape_i.IsNull()) {
224 Standard_NullObject::Raise("In Partition a Keep Inside shape is null");
227 //BRepBuilderAPI_Copy aCopyTool (aShape_i);
228 TopoDS_Shape aShape_i_copy;
229 TNaming_CopyShape::CopyTool(aShape_i, aMapTShapes, aShape_i_copy);
230 //if (aCopyTool.IsDone())
231 // aShape_i_copy = aCopyTool.Shape();
233 // Standard_NullObject::Raise("Bad shape detected");
235 // fill aCopyMap for history
236 TopTools_IndexedMapOfShape aShape_i_inds;
237 TopTools_IndexedMapOfShape aShape_i_copy_inds;
238 TopExp::MapShapes(aShape_i, aShape_i_inds);
239 TopExp::MapShapes(aShape_i_copy, aShape_i_copy_inds);
240 Standard_Integer nbInds = aShape_i_inds.Extent();
241 for (Standard_Integer ie = 1; ie <= nbInds; ie++) {
242 aCopyMap.Bind(aShape_i_inds.FindKey(ie), aShape_i_copy_inds.FindKey(ie));
245 TopTools_ListOfShape aSimpleShapes;
246 //PrepareShapes(aShape_i, aType, aSimpleShapes);
247 PrepareShapes(aShape_i_copy, aType, aSimpleShapes);
248 TopTools_ListIteratorOfListOfShape aSimpleIter (aSimpleShapes);
249 for (; aSimpleIter.More(); aSimpleIter.Next()) {
250 const TopoDS_Shape& aSimpleSh = aSimpleIter.Value();
251 if (!ToolsMap.Contains(aSimpleSh) && ShapesMap.Add(aSimpleSh))
252 PS.AddArgument(aSimpleSh);
256 // add shapes that are in ListRemoveInside, as object shapes;
257 for (ind = 1; ind <= aRemIns->Length(); ind++) {
258 Handle(GEOM_Function) aRefShape = Handle(GEOM_Function)::DownCast(aRemIns->Value(ind));
259 TopoDS_Shape aShape_i = aRefShape->GetValue();
260 if (aShape_i.IsNull()) {
261 Standard_NullObject::Raise("In Partition a Remove Inside shape is null");
264 //BRepBuilderAPI_Copy aCopyTool (aShape_i);
265 TopoDS_Shape aShape_i_copy;
266 TNaming_CopyShape::CopyTool(aShape_i, aMapTShapes, aShape_i_copy);
267 //if (aCopyTool.IsDone())
268 // aShape_i_copy = aCopyTool.Shape();
270 // Standard_NullObject::Raise("Bad shape detected");
272 // fill aCopyMap for history
273 TopTools_IndexedMapOfShape aShape_i_inds;
274 TopTools_IndexedMapOfShape aShape_i_copy_inds;
275 TopExp::MapShapes(aShape_i, aShape_i_inds);
276 TopExp::MapShapes(aShape_i_copy, aShape_i_copy_inds);
277 Standard_Integer nbInds = aShape_i_inds.Extent();
278 for (Standard_Integer ie = 1; ie <= nbInds; ie++) {
279 aCopyMap.Bind(aShape_i_inds.FindKey(ie), aShape_i_copy_inds.FindKey(ie));
282 TopTools_ListOfShape aSimpleShapes;
283 //PrepareShapes(aShape_i, aType, aSimpleShapes);
284 PrepareShapes(aShape_i_copy, aType, aSimpleShapes);
285 TopTools_ListIteratorOfListOfShape aSimpleIter (aSimpleShapes);
286 for (; aSimpleIter.More(); aSimpleIter.Next()) {
287 const TopoDS_Shape& aSimpleSh = aSimpleIter.Value();
288 if (!ToolsMap.Contains(aSimpleSh) && ShapesMap.Add(aSimpleSh))
289 PS.AddArgument(aSimpleSh);
293 PS.SetLimitMode(aCI.GetKeepNonlimitShapes());
294 PS.SetLimit((TopAbs_ShapeEnum)aCI.GetLimit());
298 //skl PS.SetRemoveWebs(!DoRemoveWebs);
299 //skl PS.Build((TopAbs_ShapeEnum) aCI.GetLimit());
301 // suppress result outside of shapes in KInsideMap
302 for (ind = 1; ind <= aKeepIns->Length(); ind++) {
303 Handle(GEOM_Function) aRefShape = Handle(GEOM_Function)::DownCast(aKeepIns->Value(ind));
304 TopoDS_Shape aShape_i = aRefShape->GetValue();
305 PS.KeepShapesInside(aShape_i);
308 // suppress result inside of shapes in RInsideMap
309 for (ind = 1; ind <= aRemIns->Length(); ind++) {
310 Handle(GEOM_Function) aRefShape = Handle(GEOM_Function)::DownCast(aRemIns->Value(ind));
311 TopoDS_Shape aShape_i = aRefShape->GetValue();
312 PS.RemoveShapesInside(aShape_i);
316 else if (aType == PARTITION_HALF)
318 Handle(GEOM_Function) aRefShape = aCI.GetShape();
319 Handle(GEOM_Function) aRefPlane = aCI.GetPlane();
320 TopoDS_Shape aShapeArg = aRefShape->GetValue();
321 TopoDS_Shape aPlaneArg = aRefPlane->GetValue();
323 if (aShapeArg.IsNull() || aPlaneArg.IsNull()) {
324 Standard_NullObject::Raise("In Half Partition a shape or a plane is null");
327 TopoDS_Shape aShapeArg_copy;
328 TopoDS_Shape aPlaneArg_copy;
330 TNaming_CopyShape::CopyTool(aShapeArg, aMapTShapes, aShapeArg_copy);
331 //BRepBuilderAPI_Copy aCopyTool (aShapeArg);
332 //if (aCopyTool.IsDone())
333 // aShapeArg_copy = aCopyTool.Shape();
335 // Standard_NullObject::Raise("Bad shape detected");
337 // fill aCopyMap for history
338 TopTools_IndexedMapOfShape aShapeArg_inds;
339 TopTools_IndexedMapOfShape aShapeArg_copy_inds;
340 TopExp::MapShapes(aShapeArg, aShapeArg_inds);
341 TopExp::MapShapes(aShapeArg_copy, aShapeArg_copy_inds);
342 Standard_Integer nbInds = aShapeArg_inds.Extent();
343 for (Standard_Integer ie = 1; ie <= nbInds; ie++) {
344 aCopyMap.Bind(aShapeArg_inds.FindKey(ie), aShapeArg_copy_inds.FindKey(ie));
348 TNaming_CopyShape::CopyTool(aPlaneArg, aMapTShapes, aPlaneArg_copy);
349 //BRepBuilderAPI_Copy aCopyTool (aPlaneArg);
350 //if (aCopyTool.IsDone())
351 // aPlaneArg_copy = aCopyTool.Shape();
353 // Standard_NullObject::Raise("Bad shape detected");
355 // fill aCopyMap for history
356 TopTools_IndexedMapOfShape aPlaneArg_inds;
357 TopTools_IndexedMapOfShape aPlaneArg_copy_inds;
358 TopExp::MapShapes(aPlaneArg, aPlaneArg_inds);
359 TopExp::MapShapes(aPlaneArg_copy, aPlaneArg_copy_inds);
360 Standard_Integer nbInds = aPlaneArg_inds.Extent();
361 for (Standard_Integer ie = 1; ie <= nbInds; ie++) {
362 aCopyMap.Bind(aPlaneArg_inds.FindKey(ie), aPlaneArg_copy_inds.FindKey(ie));
366 // add object shapes that are in ListShapes;
367 PS.AddArgument(aShapeArg_copy);
368 //PS.AddShape(aShapeArg);
370 // add tool shapes that are in ListTools and not in ListShapes;
371 PS.AddTool(aPlaneArg_copy);
372 //PS.AddTool(aPlaneArg);
376 //PS.SetRemoveWebs(Standard_False);
377 //PS.Build(aShapeArg.ShapeType());
383 if (aShape.IsNull()) {
384 // Mantis issue 22009
385 if (PS.ErrorStatus() == 100 && PS.Tools().Extent() == 0 && PS.Arguments().Extent() == 1)
386 aShape = PS.Arguments().First();
391 //Alternative case to check not valid partition IPAL21418
392 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
394 for (; It.More(); It.Next())
397 Standard_ConstructionError::Raise("Partition aborted : non valid shape result");
400 if (!BRepAlgo::IsValid(aShape)) {
401 // 08.07.2008 added by skl during fixing bug 19761 from Mantis
402 ShapeFix_ShapeTolerance aSFT;
403 aSFT.LimitTolerance(aShape, Precision::Confusion(),
404 Precision::Confusion(), TopAbs_SHAPE);
405 Handle(ShapeFix_Shape) aSfs = new ShapeFix_Shape(aShape);
407 aShape = aSfs->Shape();
408 if (!BRepAlgo::IsValid(aShape))
409 Standard_ConstructionError::Raise("Partition aborted : non valid shape result");
412 aFunction->SetValue(aShape);
414 // Fill history to be used by GetInPlace functionality
415 TopTools_IndexedMapOfShape aResIndices;
416 TopExp::MapShapes(aShape, aResIndices);
418 // Map: source_shape/images of source_shape in Result
419 const BOPCol_IndexedDataMapOfShapeListOfShape& aMR = PS.ImagesResult();
420 //const TopTools_IndexedDataMapOfShapeListOfShape& aMR = PS.ImagesResult();
422 // history for all argument shapes
423 // be sure to use aCopyMap
424 TDF_LabelSequence aLabelSeq;
425 aFunction->GetDependency(aLabelSeq);
426 Standard_Integer nbArg = aLabelSeq.Length();
428 for (Standard_Integer iarg = 1; iarg <= nbArg; iarg++) {
430 TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
432 Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
433 TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
435 TopTools_IndexedMapOfShape anArgumentIndices;
436 TopExp::MapShapes(anArgumentShape, anArgumentIndices);
437 Standard_Integer nbArgumentEntities = anArgumentIndices.Extent();
439 // Find corresponding label in history
440 TDF_Label anArgumentHistoryLabel =
441 aFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_True);
443 for (Standard_Integer ie = 1; ie <= nbArgumentEntities; ie++) {
444 TopoDS_Shape anEntity = anArgumentIndices.FindKey(ie);
445 // be sure to use aCopyMap here
446 if (aCopyMap.IsBound(anEntity))
447 anEntity = aCopyMap.Find(anEntity);
449 if (!aMR.Contains(anEntity)) continue;
451 const BOPCol_ListOfShape& aModified = aMR.FindFromKey(anEntity);
452 //const TopTools_ListOfShape& aModified = aMR.FindFromKey(anEntity);
453 Standard_Integer nbModified = aModified.Extent();
455 if (nbModified > 0) { // Mantis issue 0021182
457 BOPCol_ListIteratorOfListOfShape itM (aModified);
458 for (; itM.More() && nbModified > 0; itM.Next(), ++ih) {
459 if (!aResIndices.Contains(itM.Value())) {
464 if (nbModified > 0) {
465 TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(ie, Standard_True);
466 Handle(TDataStd_IntegerArray) anAttr =
467 TDataStd_IntegerArray::Set(aWhatHistoryLabel, 1, nbModified);
470 BOPCol_ListIteratorOfListOfShape itM (aModified);
471 //TopTools_ListIteratorOfListOfShape itM (aModified);
472 for (; itM.More(); itM.Next(), ++ih) {
473 int id = aResIndices.FindIndex(itM.Value());
474 anAttr->SetValue(ih, id);
480 log.SetTouched(Label());
485 //================================================================================
487 * \brief Returns a name of creation operation and names and values of creation parameters
489 //================================================================================
491 bool GEOMImpl_PartitionDriver::
492 GetCreationInformation(std::string& theOperationName,
493 std::vector<GEOM_Param>& theParams)
495 if (Label().IsNull()) return 0;
496 Handle(GEOM_Function) function = GEOM_Function::GetFunction(Label());
498 GEOMImpl_IPartition aCI( function );
499 Standard_Integer aType = function->GetType();
501 theOperationName = "PARTITION";
504 case PARTITION_PARTITION:
505 case PARTITION_NO_SELF_INTERSECTIONS:
506 AddParam( theParams, "Objects", aCI.GetShapes() );
507 AddParam( theParams, "Tool objects", aCI.GetTools() );
509 Handle(TColStd_HSequenceOfTransient) objSeq = aCI.GetKeepIns();
510 if ( !objSeq.IsNull() && objSeq->Length() > 0 )
511 AddParam( theParams, "Objects to keep inside", objSeq );
512 objSeq = aCI.GetRemoveIns();
513 if ( !objSeq.IsNull() && objSeq->Length() > 0 )
514 AddParam( theParams, "Objects to remove inside", objSeq );
515 Handle(TColStd_HArray1OfInteger) intSeq = aCI.GetMaterials();
516 if ( !intSeq.IsNull() && intSeq->Length() > 0 )
517 AddParam( theParams, "Materials", aCI.GetMaterials() );
519 AddParam( theParams, "Resulting type", (TopAbs_ShapeEnum) aCI.GetLimit());
520 AddParam( theParams, "Keep shapes of lower type", aCI.GetKeepNonlimitShapes());
521 AddParam( theParams, "No object intersections", ( aType == PARTITION_NO_SELF_INTERSECTIONS ));
524 AddParam( theParams, "Object", aCI.GetShape() );
525 AddParam( theParams, "Plane", aCI.GetPlane() );
534 IMPLEMENT_STANDARD_HANDLE (GEOMImpl_PartitionDriver,GEOM_BaseDriver);
535 IMPLEMENT_STANDARD_RTTIEXT (GEOMImpl_PartitionDriver,GEOM_BaseDriver);