From: skv Date: Thu, 28 Jan 2016 14:08:15 +0000 (+0300) Subject: 0052919: Build shell with two brep files creates suspected result X-Git-Tag: V8_0_0rc1~3^2 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=a4a4fee20cf2481d300bc74fe84c5d7b2c1e5851;p=modules%2Fgeom.git 0052919: Build shell with two brep files creates suspected result --- diff --git a/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx b/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx index 8b585f83e..5072071be 100644 --- a/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx @@ -73,6 +73,8 @@ #include #include +#include +#include #include #include @@ -161,6 +163,165 @@ namespace return result; } + + /** + * This function constructs a shell or a compound of shells from a set of faces and/or shells. + * + * @param theShapes is a set of faces and/or shells. + * @return a shell or a compound of shells. + */ + TopoDS_Shape makeShellFromFaces + (const Handle(TColStd_HSequenceOfTransient) &theShapes) + { + const Standard_Integer aNbShapes = theShapes->Length(); + Standard_Integer i; + TopTools_ListOfShape aListFaces; + TopTools_MapOfShape aMapFence; + BRep_Builder aBuilder; + + // Fill the list of unique faces + for (i = 1; i <= aNbShapes; ++i) { + // Function + const Handle(GEOM_Function) aRefShape = + Handle(GEOM_Function)::DownCast(theShapes->Value(i)); + + if (aRefShape.IsNull()) { + Standard_NullObject::Raise("Face for shell construction is null"); + } + + // Shape + const TopoDS_Shape aShape = aRefShape->GetValue(); + + if (aShape.IsNull()) { + Standard_NullObject::Raise("Face for shell construction is null"); + } + + // Shape type + const TopAbs_ShapeEnum aType = aShape.ShapeType(); + + if (aType == TopAbs_SHELL) { + // Get faces. + TopExp_Explorer anExp(aShape, TopAbs_FACE); + + for (; anExp.More(); anExp.Next()) { + const TopoDS_Shape &aFace = anExp.Current(); + + if (aMapFence.Add(aFace)) { + aListFaces.Append(aFace); + } + } + } else if (aType == TopAbs_FACE) { + // Append the face in the list + if (aMapFence.Add(aShape)) { + aListFaces.Append(aShape); + } + } else { + Standard_TypeMismatch::Raise + ("Shape for shell construction is neither a shell nor a face"); + } + } + + // Perform computation of shells. + TopTools_ListOfShape aListShells; + TopTools_ListIteratorOfListOfShape anIter; + + while (!aListFaces.IsEmpty()) { + // Perform sewing + BRepBuilderAPI_Sewing aSewing(Precision::Confusion()*10.0); + + for (anIter.Initialize(aListFaces); anIter.More(); anIter.Next()) { + aSewing.Add(anIter.Value()); + } + + aSewing.Perform(); + + // Fill list of shells. + const TopoDS_Shape &aSewed = aSewing.SewedShape(); + TopExp_Explorer anExp(aSewed, TopAbs_SHELL); + Standard_Boolean isNewShells = Standard_False; + + // Append shells + for (; anExp.More(); anExp.Next()) { + aListShells.Append(anExp.Current()); + isNewShells = Standard_True; + } + + // Append single faces. + anExp.Init(aSewed, TopAbs_FACE, TopAbs_SHELL); + + for (; anExp.More(); anExp.Next()) { + TopoDS_Shell aShell; + + aBuilder.MakeShell(aShell); + aBuilder.Add(aShell, anExp.Current()); + aListShells.Append(aShell); + isNewShells = Standard_True; + } + + if (!isNewShells) { + // There are no more shell can be obtained. Break the loop. + break; + } + + // Remove faces that are in the result from the list. + TopTools_IndexedMapOfShape aMapFaces; + + TopExp::MapShapes(aSewed, TopAbs_FACE, aMapFaces); + + // Add deleted faces to the map + const Standard_Integer aNbDelFaces = aSewing.NbDeletedFaces(); + + for (i = 1; i <= aNbDelFaces; ++i) { + aMapFaces.Add(aSewing.DeletedFace(i)); + } + + for (anIter.Initialize(aListFaces); anIter.More();) { + const TopoDS_Shape &aFace = anIter.Value(); + Standard_Boolean isFaceUsed = Standard_False; + + if (aMapFaces.Contains(aFace) || aSewing.IsModified(aFace)) { + // Remove face from the list. + aListFaces.Remove(anIter); + } else { + // Go to the next face. + anIter.Next(); + } + } + } + + // If there are faces not used in shells create a shell for each face. + for (anIter.Initialize(aListFaces); anIter.More(); anIter.Next()) { + TopoDS_Shell aShell; + + aBuilder.MakeShell(aShell); + aBuilder.Add(aShell, anIter.Value()); + aListShells.Append(aShell); + } + + // Construct the result that can be either a shell or a compound of shells + TopoDS_Shape aResult; + + if (!aListShells.IsEmpty()) { + if (aListShells.Extent() == 1) { + aResult = aListShells.First(); + } else { + // There are more then one shell. + TopoDS_Compound aCompound; + + aBuilder.MakeCompound(aCompound); + + for (anIter.Initialize(aListShells); anIter.More(); anIter.Next()) { + aBuilder.Add(aCompound, anIter.Value()); + } + + aResult = aCompound; + } + } + + return aResult; + } + + // End of namespace } //modified by NIZNHY-PKV Wed Dec 28 13:48:20 2011f @@ -432,60 +593,13 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const allowCompound = true; Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes(); - unsigned int ind, nbshapes = aShapes->Length(); - // add faces - BRepBuilderAPI_Sewing aSewing (Precision::Confusion()*10.0); - for (ind = 1; ind <= nbshapes; ind++) { - Handle(GEOM_Function) aRefShape = Handle(GEOM_Function)::DownCast(aShapes->Value(ind)); - TopoDS_Shape aShape_i = aRefShape->GetValue(); - if (aShape_i.IsNull()) { - Standard_NullObject::Raise("Face for shell construction is null"); - } - aSewing.Add(aShape_i); - } - - aSewing.Perform(); - - TopoDS_Shape sh = aSewing.SewedShape(); - - if (sh.ShapeType()==TopAbs_FACE && nbshapes==1) { - // case for creation of shell from one face - PAL12722 (skl 26.06.2006) - TopoDS_Shell ss; - B.MakeShell(ss); - B.Add(ss,sh); - aShape = ss; - } - else { - //TopExp_Explorer exp (aSewing.SewedShape(), TopAbs_SHELL); - TopExp_Explorer exp (sh, TopAbs_SHELL); - Standard_Integer ish = 0; - for (; exp.More(); exp.Next()) { - aShape = exp.Current(); - ish++; - } - - if (ish != 1) { - // try the case of one face (Mantis issue 0021809) - TopExp_Explorer expF (sh, TopAbs_FACE); - Standard_Integer ifa = 0; - for (; expF.More(); expF.Next()) { - aShape = expF.Current(); - ifa++; - } - - if (ifa == 1) { - TopoDS_Shell ss; - B.MakeShell(ss); - B.Add(ss,aShape); - aShape = ss; - } - else { - aShape = aSewing.SewedShape(); - } - } + if (aShapes.IsNull()) { + Standard_NullObject::Raise("Argument Shapes is null"); } + // Compute a shell or a compound of shells. + aShape = makeShellFromFaces(aShapes); } else if (aType == SOLID_SHELLS) { // result may be only a solid or a compound of solids