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_PartitionDriver.hxx>
25 #include <GEOMImpl_IPartition.hxx>
26 #include <GEOMImpl_Types.hxx>
28 #include <GEOM_Object.hxx>
29 #include <GEOM_Function.hxx>
31 //#include <NMTAlgo_Splitter1.hxx>
32 #include <GEOMAlgo_Splitter.hxx>
33 #include <TopTools_IndexedMapOfShape.hxx>
35 #include <TDataStd_IntegerArray.hxx>
37 #include <BRep_Tool.hxx>
38 #include <BRepAlgo.hxx>
43 #include <TopoDS_Shape.hxx>
44 #include <TopoDS_Vertex.hxx>
45 #include <TopoDS_Wire.hxx>
46 #include <TopoDS_Iterator.hxx>
47 #include <TopTools_MapOfShape.hxx>
48 #include <TopTools_ListIteratorOfListOfShape.hxx>
50 #include <ShapeFix_ShapeTolerance.hxx>
51 #include <ShapeFix_Shape.hxx>
53 #include <TColStd_ListIteratorOfListOfInteger.hxx>
54 #include <TColStd_ListOfInteger.hxx>
55 #include <Standard_NullObject.hxx>
56 #include <Precision.hxx>
59 //=======================================================================
62 //=======================================================================
63 const Standard_GUID& GEOMImpl_PartitionDriver::GetID()
65 static Standard_GUID aPartitionDriver("FF1BBB22-5D14-4df2-980B-3A668264EA16");
66 return aPartitionDriver;
70 //=======================================================================
71 //function : GEOMImpl_PartitionDriver
73 //=======================================================================
74 GEOMImpl_PartitionDriver::GEOMImpl_PartitionDriver()
78 //=======================================================================
79 //function : SimplifyCompound
81 //=======================================================================
82 static void PrepareShapes (const TopoDS_Shape& theShape,
83 Standard_Integer theType,
84 TopTools_ListOfShape& theSimpleList)
86 if (theType == PARTITION_NO_SELF_INTERSECTIONS ||
87 theShape.ShapeType() != TopAbs_COMPOUND) {
88 theSimpleList.Append(theShape);
92 // explode compound on simple shapes to allow their intersections
93 TopoDS_Iterator It (theShape, Standard_True, Standard_True);
94 TopTools_MapOfShape mapShape;
95 for (; It.More(); It.Next()) {
96 if (mapShape.Add(It.Value())) {
97 TopoDS_Shape curSh = It.Value();
98 PrepareShapes(curSh, theType, theSimpleList);
103 //=======================================================================
106 //=======================================================================
107 Standard_Integer GEOMImpl_PartitionDriver::Execute(TFunction_Logbook& log) const
109 if (Label().IsNull()) return 0;
110 Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
112 GEOMImpl_IPartition aCI (aFunction);
113 Standard_Integer aType = aFunction->GetType();
116 //sklNMTAlgo_Splitter1 PS;
117 GEOMAlgo_Splitter PS;
119 if (aType == PARTITION_PARTITION || aType == PARTITION_NO_SELF_INTERSECTIONS)
121 Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes();
122 Handle(TColStd_HSequenceOfTransient) aTools = aCI.GetTools();
123 Handle(TColStd_HSequenceOfTransient) aKeepIns = aCI.GetKeepIns();
124 Handle(TColStd_HSequenceOfTransient) aRemIns = aCI.GetRemoveIns();
125 Handle(TColStd_HArray1OfInteger) aMaterials = aCI.GetMaterials();
126 //skl Standard_Boolean DoRemoveWebs = !aMaterials.IsNull();
129 //unsigned int ind, nbshapes = 0;
130 //nbshapes += aShapes->Length() + aTools->Length();
131 //nbshapes += aKeepIns->Length() + aRemIns->Length();
132 //TopTools_MapOfShape ShapesMap(nbshapes), ToolsMap(nbshapes);
133 TopTools_MapOfShape ShapesMap, ToolsMap;
135 // add object shapes that are in ListShapes;
136 for (ind = 1; ind <= aShapes->Length(); ind++) {
137 Handle(GEOM_Function) aRefShape = Handle(GEOM_Function)::DownCast(aShapes->Value(ind));
138 TopoDS_Shape aShape_i = aRefShape->GetValue();
139 if (aShape_i.IsNull()) {
140 Standard_NullObject::Raise("In Partition a shape is null");
143 TopTools_ListOfShape aSimpleShapes;
144 PrepareShapes(aShape_i, aType, aSimpleShapes);
145 TopTools_ListIteratorOfListOfShape aSimpleIter (aSimpleShapes);
146 for (; aSimpleIter.More(); aSimpleIter.Next()) {
147 const TopoDS_Shape& aSimpleSh = aSimpleIter.Value();
148 if (ShapesMap.Add(aSimpleSh)) {
149 PS.AddShape(aSimpleSh);
150 //skl if (DoRemoveWebs) {
151 //skl if (aMaterials->Length() >= ind)
152 //skl PS.SetMaterial(aSimpleSh, aMaterials->Value(ind));
158 // add tool shapes that are in ListTools and not in ListShapes;
159 for (ind = 1; ind <= aTools->Length(); ind++) {
160 Handle(GEOM_Function) aRefShape = Handle(GEOM_Function)::DownCast(aTools->Value(ind));
161 TopoDS_Shape aShape_i = aRefShape->GetValue();
162 if (aShape_i.IsNull()) {
163 Standard_NullObject::Raise("In Partition a tool shape is null");
166 TopTools_ListOfShape aSimpleShapes;
167 PrepareShapes(aShape_i, aType, aSimpleShapes);
168 TopTools_ListIteratorOfListOfShape aSimpleIter (aSimpleShapes);
169 for (; aSimpleIter.More(); aSimpleIter.Next()) {
170 const TopoDS_Shape& aSimpleSh = aSimpleIter.Value();
171 if (!ShapesMap.Contains(aSimpleSh) && ToolsMap.Add(aSimpleSh)) {
172 PS.AddTool(aSimpleSh);
177 // add shapes that are in ListKeepInside, as object shapes;
178 for (ind = 1; ind <= aKeepIns->Length(); ind++) {
179 Handle(GEOM_Function) aRefShape = Handle(GEOM_Function)::DownCast(aKeepIns->Value(ind));
180 TopoDS_Shape aShape_i = aRefShape->GetValue();
181 if (aShape_i.IsNull()) {
182 Standard_NullObject::Raise("In Partition a Keep Inside shape is null");
185 TopTools_ListOfShape aSimpleShapes;
186 PrepareShapes(aShape_i, aType, aSimpleShapes);
187 TopTools_ListIteratorOfListOfShape aSimpleIter (aSimpleShapes);
188 for (; aSimpleIter.More(); aSimpleIter.Next()) {
189 const TopoDS_Shape& aSimpleSh = aSimpleIter.Value();
190 if (!ToolsMap.Contains(aSimpleSh) && ShapesMap.Add(aSimpleSh))
191 PS.AddShape(aSimpleSh);
195 // add shapes that are in ListRemoveInside, as object shapes;
196 for (ind = 1; ind <= aRemIns->Length(); ind++) {
197 Handle(GEOM_Function) aRefShape = Handle(GEOM_Function)::DownCast(aRemIns->Value(ind));
198 TopoDS_Shape aShape_i = aRefShape->GetValue();
199 if (aShape_i.IsNull()) {
200 Standard_NullObject::Raise("In Partition a Remove Inside shape is null");
203 TopTools_ListOfShape aSimpleShapes;
204 PrepareShapes(aShape_i, aType, aSimpleShapes);
205 TopTools_ListIteratorOfListOfShape aSimpleIter (aSimpleShapes);
206 for (; aSimpleIter.More(); aSimpleIter.Next()) {
207 const TopoDS_Shape& aSimpleSh = aSimpleIter.Value();
208 if (!ToolsMap.Contains(aSimpleSh) && ShapesMap.Add(aSimpleSh))
209 PS.AddShape(aSimpleSh);
213 PS.SetLimitMode(aCI.GetKeepNonlimitShapes());
214 PS.SetLimit( (TopAbs_ShapeEnum)aCI.GetLimit() );
218 //skl PS.SetRemoveWebs(!DoRemoveWebs);
219 //skl PS.Build((TopAbs_ShapeEnum) aCI.GetLimit());
221 // suppress result outside of shapes in KInsideMap
222 for (ind = 1; ind <= aKeepIns->Length(); ind++) {
223 Handle(GEOM_Function) aRefShape = Handle(GEOM_Function)::DownCast(aKeepIns->Value(ind));
224 TopoDS_Shape aShape_i = aRefShape->GetValue();
225 PS.KeepShapesInside(aShape_i);
228 // suppress result inside of shapes in RInsideMap
229 for (ind = 1; ind <= aRemIns->Length(); ind++) {
230 Handle(GEOM_Function) aRefShape = Handle(GEOM_Function)::DownCast(aRemIns->Value(ind));
231 TopoDS_Shape aShape_i = aRefShape->GetValue();
232 PS.RemoveShapesInside(aShape_i);
236 else if (aType == PARTITION_HALF)
238 Handle(GEOM_Function) aRefShape = aCI.GetShape();
239 Handle(GEOM_Function) aRefPlane = aCI.GetPlane();
240 TopoDS_Shape aShapeArg = aRefShape->GetValue();
241 TopoDS_Shape aPlaneArg = aRefPlane->GetValue();
243 if (aShapeArg.IsNull() || aPlaneArg.IsNull()) {
244 Standard_NullObject::Raise("In Half Partition a shape or a plane is null");
247 // add object shapes that are in ListShapes;
248 PS.AddShape(aShapeArg);
250 // add tool shapes that are in ListTools and not in ListShapes;
251 PS.AddTool(aPlaneArg);
255 //PS.SetRemoveWebs(Standard_False);
256 //PS.Build(aShapeArg.ShapeType());
262 if (aShape.IsNull()) return 0;
264 //Alternative case to check not valid partition IPAL21418
265 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
267 for (; It.More(); It.Next())
270 Standard_ConstructionError::Raise("Partition aborted : non valid shape result");
273 if (!BRepAlgo::IsValid(aShape)) {
274 // 08.07.2008 added by skl during fixing bug 19761 from Mantis
275 ShapeFix_ShapeTolerance aSFT;
276 aSFT.LimitTolerance(aShape, Precision::Confusion(),
277 Precision::Confusion(), TopAbs_SHAPE);
278 Handle(ShapeFix_Shape) aSfs = new ShapeFix_Shape(aShape);
280 aShape = aSfs->Shape();
281 if (!BRepAlgo::IsValid(aShape))
282 Standard_ConstructionError::Raise("Partition aborted : non valid shape result");
285 aFunction->SetValue(aShape);
287 // Fill history to be used by GetInPlace functionality
288 TopTools_IndexedMapOfShape aResIndices;
289 TopExp::MapShapes(aShape, aResIndices);
291 // Map: source_shape/images of source_shape in Result
292 const TopTools_IndexedDataMapOfShapeListOfShape& aMR = PS.ImagesResult();
294 // history for all argument shapes
295 TDF_LabelSequence aLabelSeq;
296 aFunction->GetDependency(aLabelSeq);
297 Standard_Integer nbArg = aLabelSeq.Length();
299 for (Standard_Integer iarg = 1; iarg <= nbArg; iarg++) {
301 TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
303 Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
304 TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
306 TopTools_IndexedMapOfShape anArgumentIndices;
307 TopExp::MapShapes(anArgumentShape, anArgumentIndices);
308 Standard_Integer nbArgumentEntities = anArgumentIndices.Extent();
310 // Find corresponding label in history
311 TDF_Label anArgumentHistoryLabel =
312 aFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_True);
314 for (Standard_Integer ie = 1; ie <= nbArgumentEntities; ie++) {
315 TopoDS_Shape anEntity = anArgumentIndices.FindKey(ie);
316 if (!aMR.Contains(anEntity)) continue;
318 const TopTools_ListOfShape& aModified = aMR.FindFromKey(anEntity);
319 Standard_Integer nbModified = aModified.Extent();
321 if (nbModified > 0) {
322 TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(ie, Standard_True);
323 Handle(TDataStd_IntegerArray) anAttr =
324 TDataStd_IntegerArray::Set(aWhatHistoryLabel, 1, nbModified);
327 TopTools_ListIteratorOfListOfShape itM (aModified);
328 for (; itM.More(); itM.Next(), ++ih) {
329 int id = aResIndices.FindIndex(itM.Value());
330 anAttr->SetValue(ih, id);
336 log.SetTouched(Label());
342 //=======================================================================
343 //function : GEOMImpl_PartitionDriver_Type_
345 //=======================================================================
346 Standard_EXPORT Handle_Standard_Type& GEOMImpl_PartitionDriver_Type_()
349 static Handle_Standard_Type aType1 = STANDARD_TYPE(TFunction_Driver);
350 if ( aType1.IsNull()) aType1 = STANDARD_TYPE(TFunction_Driver);
351 static Handle_Standard_Type aType2 = STANDARD_TYPE(MMgt_TShared);
352 if ( aType2.IsNull()) aType2 = STANDARD_TYPE(MMgt_TShared);
353 static Handle_Standard_Type aType3 = STANDARD_TYPE(Standard_Transient);
354 if ( aType3.IsNull()) aType3 = STANDARD_TYPE(Standard_Transient);
357 static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,aType3,NULL};
358 static Handle_Standard_Type _aType = new Standard_Type("GEOMImpl_PartitionDriver",
359 sizeof(GEOMImpl_PartitionDriver),
361 (Standard_Address)_Ancestors,
362 (Standard_Address)NULL);
367 //=======================================================================
368 //function : DownCast
370 //=======================================================================
371 const Handle(GEOMImpl_PartitionDriver) Handle(GEOMImpl_PartitionDriver)::DownCast(const Handle(Standard_Transient)& AnObject)
373 Handle(GEOMImpl_PartitionDriver) _anOtherObject;
375 if (!AnObject.IsNull()) {
376 if (AnObject->IsKind(STANDARD_TYPE(GEOMImpl_PartitionDriver))) {
377 _anOtherObject = Handle(GEOMImpl_PartitionDriver)((Handle(GEOMImpl_PartitionDriver)&)AnObject);
381 return _anOtherObject ;