#include <TopoDS_Compound.hxx>
#include <TopoDS_Iterator.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
#include <TopTools_MapOfShape.hxx>
#include <TopTools_HSequenceOfShape.hxx>
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
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