NPAL13902: Create face from edges.

This commit is contained in:
jfa 2007-10-12 08:28:53 +00:00
parent 791c95dab2
commit 8e483143ae

View File

@ -18,11 +18,9 @@
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
// //
#include <Standard_Stream.hxx>
#include <GEOMImpl_ShapeDriver.hxx> #include <GEOMImpl_ShapeDriver.hxx>
#include <GEOMImpl_IShapes.hxx> #include <GEOMImpl_IShapes.hxx>
#include <GEOMImpl_IShapesOperations.hxx>
#include <GEOMImpl_Types.hxx> #include <GEOMImpl_Types.hxx>
#include <GEOMImpl_Block6Explorer.hxx> #include <GEOMImpl_Block6Explorer.hxx>
@ -36,12 +34,14 @@
#include <BRepAlgo_FaceRestrictor.hxx> #include <BRepAlgo_FaceRestrictor.hxx>
#include <BRepBuilderAPI_Sewing.hxx> #include <BRepBuilderAPI_Sewing.hxx>
#include <BRepBuilderAPI_Copy.hxx> #include <BRepBuilderAPI_Copy.hxx>
#include <BRepTools_Quilt.hxx>
#include <BRepCheck.hxx> #include <BRepCheck.hxx>
#include <BRepCheck_Analyzer.hxx> #include <BRepCheck_Analyzer.hxx>
#include <BRepCheck_Shell.hxx> #include <BRepCheck_Shell.hxx>
#include <BRepClass3d_SolidClassifier.hxx> #include <BRepClass3d_SolidClassifier.hxx>
#include <BRepBuilderAPI_MakeWire.hxx> #include <BRepBuilderAPI_MakeWire.hxx>
#include <BRepBuilderAPI_Sewing.hxx>
#include <ShapeAnalysis_FreeBounds.hxx>
#include <TopAbs.hxx> #include <TopAbs.hxx>
#include <TopoDS.hxx> #include <TopoDS.hxx>
@ -53,9 +53,11 @@
#include <TopoDS_Compound.hxx> #include <TopoDS_Compound.hxx>
#include <TopoDS_Iterator.hxx> #include <TopoDS_Iterator.hxx>
#include <TopExp_Explorer.hxx> #include <TopExp_Explorer.hxx>
#include <TopTools_MapOfShape.hxx> #include <TopTools_MapOfShape.hxx>
#include <TopTools_SequenceOfShape.hxx> #include <TopTools_HSequenceOfShape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TColStd_HSequenceOfTransient.hxx>
#include <Precision.hxx> #include <Precision.hxx>
#include <Standard_NullObject.hxx> #include <Standard_NullObject.hxx>
@ -182,75 +184,79 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const
} }
} }
else if (aType == FACE_WIRES) { else if (aType == FACE_WIRES) {
// Try to build a face from a set of wires and edges
int ind;
Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes(); Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes();
int nbshapes = aShapes->Length(); int nbshapes = aShapes->Length();
if (nbshapes < 1) { if (nbshapes < 1) {
Standard_ConstructionError::Raise("No wires given"); Standard_ConstructionError::Raise("No wires or edges given");
} }
// first wire or edge // 1. Extract all edges from the given arguments
Handle(GEOM_Function) aRefWire = Handle(GEOM_Function)::DownCast(aShapes->Value(1)); TopTools_MapOfShape aMapEdges;
TopoDS_Shape aWire = aRefWire->GetValue(); Handle(TopTools_HSequenceOfShape) aSeqEdgesIn = new TopTools_HSequenceOfShape;
if (aWire.IsNull()) Standard_NullObject::Raise("Argument Shape is null");
TopoDS_Wire W1; BRep_Builder B;
if(aWire.ShapeType() == TopAbs_WIRE) { for (ind = 1; ind <= nbshapes; ind++) {
W1 = TopoDS::Wire(aWire); Handle(GEOM_Function) aRefSh_i = Handle(GEOM_Function)::DownCast(aShapes->Value(ind));
} TopoDS_Shape aSh_i = aRefSh_i->GetValue();
else if(aWire.ShapeType() == TopAbs_EDGE && aWire.Closed()) {
BRepBuilderAPI_MakeWire MW; TopExp_Explorer anExpE_i (aSh_i, TopAbs_EDGE);
MW.Add(TopoDS::Edge(aWire)); for (; anExpE_i.More(); anExpE_i.Next()) {
if (!MW.IsDone()) { if (aMapEdges.Add(anExpE_i.Current())) {
Standard_ConstructionError::Raise("Wire construction failed"); aSeqEdgesIn->Append(anExpE_i.Current());
}
} }
W1 = MW;
}
else {
Standard_NullObject::Raise
("Shape for face construction is neither a wire nor closed edge");
} }
// basic face // 2. Connect edges to wires of maximum length
TopoDS_Shape FFace; Handle(TopTools_HSequenceOfShape) aSeqWiresOut;
GEOMImpl_Block6Explorer::MakeFace(W1, aCI.GetIsPlanar(), FFace); ShapeAnalysis_FreeBounds::ConnectEdgesToWires(aSeqEdgesIn, Precision::Confusion(),
if (FFace.IsNull()) { /*shared*/Standard_False, aSeqWiresOut);
// 3. Separate closed wires
Handle(TopTools_HSequenceOfShape) aSeqClosedWires = new TopTools_HSequenceOfShape;
Handle(TopTools_HSequenceOfShape) aSeqOpenWires = new TopTools_HSequenceOfShape;
for (ind = 1; ind <= aSeqWiresOut->Length(); ind++) {
if (aSeqWiresOut->Value(ind).Closed())
aSeqClosedWires->Append(aSeqWiresOut->Value(ind));
else
aSeqOpenWires->Append(aSeqWiresOut->Value(ind));
}
if (aSeqClosedWires->Length() < 1) {
Standard_ConstructionError::Raise
("There is no closed contour can be built from the given arguments");
}
// 4. Build a face / list of faces from all the obtained closed wires
// 4.a. Basic face
TopoDS_Shape aFFace;
TopoDS_Wire aW1 = TopoDS::Wire(aSeqClosedWires->Value(1));
GEOMImpl_Block6Explorer::MakeFace(aW1, aCI.GetIsPlanar(), aFFace);
if (aFFace.IsNull()) {
Standard_ConstructionError::Raise("Face construction failed"); Standard_ConstructionError::Raise("Face construction failed");
} }
if (nbshapes == 1) { // 4.b. Add other wires
aShape = FFace; if (aSeqClosedWires->Length() == 1) {
aShape = aFFace;
} else { }
else {
TopoDS_Compound C; TopoDS_Compound C;
BRep_Builder aBuilder; BRep_Builder aBuilder;
aBuilder.MakeCompound(C); aBuilder.MakeCompound(C);
BRepAlgo_FaceRestrictor FR; BRepAlgo_FaceRestrictor FR;
TopAbs_Orientation OriF = FFace.Orientation(); TopAbs_Orientation OriF = aFFace.Orientation();
TopoDS_Shape aLocalS = FFace.Oriented(TopAbs_FORWARD); TopoDS_Shape aLocalS = aFFace.Oriented(TopAbs_FORWARD);
FR.Init(TopoDS::Face(aLocalS), Standard_False, Standard_True); FR.Init(TopoDS::Face(aLocalS), Standard_False, Standard_True);
for (int ind = 1; ind <= nbshapes; ind++) { for (ind = 1; ind <= aSeqClosedWires->Length(); ind++) {
Handle(GEOM_Function) aRefWire_i = TopoDS_Wire aW = TopoDS::Wire(aSeqClosedWires->Value(ind));
Handle(GEOM_Function)::DownCast(aShapes->Value(ind)); FR.Add(aW);
TopoDS_Shape aWire_i = aRefWire_i->GetValue();
if (aWire_i.IsNull()) Standard_NullObject::Raise("Argument Shape is null");
TopoDS_Wire W_i;
if(aWire_i.ShapeType() == TopAbs_WIRE) {
W_i = TopoDS::Wire(aWire_i);
}
else if(aWire_i.ShapeType() == TopAbs_EDGE && aWire_i.Closed()) {
BRepBuilderAPI_MakeWire MW1;
MW1.Add(TopoDS::Edge(aWire_i));
if (!MW1.IsDone()) {
Standard_ConstructionError::Raise("Wire construction failed");
}
W_i = MW1;
}
else {
Standard_NullObject::Raise
("Shape for face construction is neither a wire nor closed edges");
}
FR.Add(W_i);
} }
FR.Perform(); FR.Perform();
@ -270,6 +276,26 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const
} }
} }
} }
// 5. Add all open wires to the result
if (aSeqOpenWires->Length() > 0) {
//Standard_ConstructionError::Raise("There are some open wires");
TopoDS_Compound C;
BRep_Builder aBuilder;
if (aSeqClosedWires->Length() == 1) {
aBuilder.MakeCompound(C);
aBuilder.Add(C, aShape);
}
else {
C = TopoDS::Compound(aShape);
}
for (ind = 1; ind <= aSeqOpenWires->Length(); ind++) {
aBuilder.Add(C, aSeqOpenWires->Value(ind));
}
aShape = C;
}
} }
else if (aType == SHELL_FACES) { else if (aType == SHELL_FACES) {
Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes(); Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes();
@ -395,13 +421,13 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const
if( Copy.IsDone() ) { if( Copy.IsDone() ) {
TopoDS_Shape tds = Copy.Shape(); TopoDS_Shape tds = Copy.Shape();
if( tds.IsNull() ) { if( tds.IsNull() ) {
Standard_ConstructionError::Raise("Orientation aborted : Can not reverse the shape"); Standard_ConstructionError::Raise("Orientation aborted : Can not reverse the shape");
} }
if( tds.Orientation() == TopAbs_FORWARD) if( tds.Orientation() == TopAbs_FORWARD)
tds.Orientation(TopAbs_REVERSED) ; tds.Orientation(TopAbs_REVERSED);
else else
tds.Orientation(TopAbs_FORWARD) ; tds.Orientation(TopAbs_FORWARD);
aShape = tds; aShape = tds;
} }
@ -462,5 +488,5 @@ const Handle(GEOMImpl_ShapeDriver) Handle(GEOMImpl_ShapeDriver)::DownCast(const
} }
} }
return _anOtherObject ; return _anOtherObject;
} }