Part: Offset: fill rework.

This commit is contained in:
blobfish 2015-03-20 15:11:09 -04:00 committed by wmayer
parent cb2002d188
commit 0950e1963a

View File

@ -152,6 +152,8 @@
# include <Transfer_TransientProcess.hxx> # include <Transfer_TransientProcess.hxx>
# include <Transfer_FinderProcess.hxx> # include <Transfer_FinderProcess.hxx>
# include <APIHeaderSection_MakeHeader.hxx> # include <APIHeaderSection_MakeHeader.hxx>
# include <ShapeAnalysis_FreeBoundsProperties.hxx>
# include <ShapeAnalysis_FreeBoundData.hxx>
#include <Base/Builder3D.h> #include <Base/Builder3D.h>
#include <Base/FileInfo.h> #include <Base/FileInfo.h>
@ -1953,9 +1955,6 @@ TopoDS_Shape TopoShape::revolve(const gp_Ax1& axis, double d, Standard_Boolean i
return mkRevol.Shape(); return mkRevol.Shape();
} }
//#include <BRepFill.hxx>
//#include <BRepTools_Quilt.hxx>
TopoDS_Shape TopoShape::makeOffsetShape(double offset, double tol, bool intersection, TopoDS_Shape TopoShape::makeOffsetShape(double offset, double tol, bool intersection,
bool selfInter, short offsetMode, short join, bool selfInter, short offsetMode, short join,
bool fill) const bool fill) const
@ -1964,85 +1963,109 @@ TopoDS_Shape TopoShape::makeOffsetShape(double offset, double tol, bool intersec
intersection ? Standard_True : Standard_False, intersection ? Standard_True : Standard_False,
selfInter ? Standard_True : Standard_False, selfInter ? Standard_True : Standard_False,
GeomAbs_JoinType(join)); GeomAbs_JoinType(join));
if (!mkOffset.IsDone())
return TopoDS_Shape(); //maybe throw exception?
const TopoDS_Shape& res = mkOffset.Shape(); const TopoDS_Shape& res = mkOffset.Shape();
if (!fill) if (!fill)
return res; return res;
#if 1
//s=Part.makePlane(10,10) //get perimeter wire of original shape.
//s.makeOffsetShape(1.0,0.01,False,False,0,0,True) //Wires returned seem to have edges in connection order.
const BRepOffset_MakeOffset& off = mkOffset.MakeOffset(); ShapeAnalysis_FreeBoundsProperties freeCheck(this->_Shape);
const BRepAlgo_Image& img = off.OffsetEdgesFromShapes(); freeCheck.Perform();
if (freeCheck.NbClosedFreeBounds() < 1)
// build up map edge->face {
TopTools_IndexedDataMapOfShapeListOfShape edge2Face; std::ostringstream stream;
TopExp::MapShapesAndAncestors(this->_Shape, TopAbs_EDGE, TopAbs_FACE, edge2Face); stream << "no closed bounds" << std::endl;
TopTools_IndexedMapOfShape mapOfShape; Base::Console().Message(stream.str().c_str());
TopExp::MapShapes(this->_Shape, TopAbs_EDGE, mapOfShape); return TopoDS_Shape(); //maybe throw exception?
}
TopoDS_Shell shell;
BRep_Builder builder; BRep_Builder builder;
TopExp_Explorer xp; TopoDS_Compound perimeterCompound;
builder.MakeShell(shell); builder.MakeCompound(perimeterCompound);
for (int index = 1; index <= freeCheck.NbClosedFreeBounds(); ++index)
for (xp.Init(this->_Shape,TopAbs_FACE); xp.More(); xp.Next()) { {
builder.Add(shell, xp.Current()); TopoDS_Wire originalWire = freeCheck.ClosedFreeBound(index)->FreeBound();
} const BRepAlgo_Image& img = mkOffset.MakeOffset().OffsetEdgesFromShapes();
for (int i=1; i<= edge2Face.Extent(); ++i) { //build offset wire.
const TopTools_ListOfShape& los = edge2Face.FindFromIndex(i); TopoDS_Wire offsetWire;
if (los.Extent() == 1) { builder.MakeWire(offsetWire);
// set the index value as user data to use it in accept() TopExp_Explorer xp;
const TopoDS_Shape& edge = edge2Face.FindKey(i); for (xp.Init(originalWire, TopAbs_EDGE); xp.More(); xp.Next())
Standard_Boolean ok = img.HasImage(edge); {
if (ok) { if (!img.HasImage(xp.Current()))
const TopTools_ListOfShape& edges = img.Image(edge); {
TopTools_ListIteratorOfListOfShape it; std::ostringstream stream;
it.Initialize(edges); stream << "no image for shape" << std::endl;
BRepOffsetAPI_ThruSections aGenerator (0,0); Base::Console().Message(stream.str().c_str());
aGenerator.AddWire(BRepBuilderAPI_MakeWire(TopoDS::Edge(edge)).Wire()); return TopoDS_Shape();
aGenerator.AddWire(BRepBuilderAPI_MakeWire(TopoDS::Edge(it.Value())).Wire());
aGenerator.Build();
for (xp.Init(aGenerator.Shape(),TopAbs_FACE); xp.More(); xp.Next()) {
builder.Add(shell, xp.Current());
}
//TopoDS_Face face = BRepFill::Face(TopoDS::Edge(edge), TopoDS::Edge(it.Value()));
//builder.Add(shell, face);
}
} }
const TopTools_ListOfShape& currentImage = img.Image(xp.Current());
TopTools_ListIteratorOfListOfShape listIt;
int edgeCount(0);
TopoDS_Edge mappedEdge;
for (listIt.Initialize(currentImage); listIt.More(); listIt.Next())
{
if (listIt.Value().ShapeType() != TopAbs_EDGE)
continue;
edgeCount++;
mappedEdge = TopoDS::Edge(listIt.Value());
}
if (edgeCount != 1)
{
std::ostringstream stream;
stream << "wrong edge count: " << edgeCount << std::endl;
Base::Console().Message(stream.str().c_str());
return TopoDS_Shape();
}
builder.Add(offsetWire, mappedEdge);
}
//It would be nice if we could get thruSections to build planar faces
//in all areas possible, so we could run through refine. I tried setting
//ruled to standard_true, but that didn't have the desired affect.
BRepOffsetAPI_ThruSections aGenerator;
aGenerator.AddWire(originalWire);
aGenerator.AddWire(offsetWire);
aGenerator.Build();
if (!aGenerator.IsDone())
{
std::ostringstream stream;
stream << "ThruSections failed" << std::endl;
Base::Console().Message(stream.str().c_str());
return TopoDS_Shape();
}
builder.Add(perimeterCompound, aGenerator.Shape());
} }
for (xp.Init(mkOffset.Shape(),TopAbs_FACE); xp.More(); xp.Next()) { //still had to sew. not using the passed in parameter for sew.
builder.Add(shell, xp.Current()); //Sew has it's own default tolerance. Opinions?
} BRepBuilderAPI_Sewing sewTool;
sewTool.Add(this->_Shape);
//BRepBuilderAPI_Sewing sew(offset); sewTool.Add(perimeterCompound);
//sew.Load(this->_Shape); sewTool.Add(res);
//sew.Add(mkOffset.Shape()); sewTool.Perform(); //Perform Sewing
//sew.Perform();
TopoDS_Shape outputShape = sewTool.SewedShape();
//shell.Closed(Standard_True); if ((outputShape.ShapeType() == TopAbs_SHELL) && (outputShape.Closed()))
{
return shell; BRepBuilderAPI_MakeSolid solidMaker(TopoDS::Shell(outputShape));
#else if (solidMaker.IsDone())
TopoDS_Solid Res; {
TopExp_Explorer exp; TopoDS_Solid temp = solidMaker.Solid();
BRep_Builder B; //contrary to the occ docs the return value OrientCloseSolid doesn't
B.MakeSolid(Res); //indicate whether the shell was open or not. It returns true with an
//open shell and we end up with an invalid solid.
BRepTools_Quilt Glue; if (BRepLib::OrientClosedSolid(temp))
for (exp.Init(this->_Shape,TopAbs_FACE); exp.More(); exp.Next()) { outputShape = temp;
Glue.Add (exp.Current()); }
}
for (exp.Init(mkOffset.Shape(),TopAbs_FACE);exp.More(); exp.Next()) {
Glue.Add (exp.Current().Reversed());
} }
TopoDS_Shape S = Glue.Shells();
for (exp.Init(S,TopAbs_SHELL); exp.More(); exp.Next()) { return outputShape;
B.Add(Res,exp.Current());
}
Res.Closed(Standard_True);
return Res;
#endif
} }
TopoDS_Shape TopoShape::makeThickSolid(const TopTools_ListOfShape& remFace, TopoDS_Shape TopoShape::makeThickSolid(const TopTools_ListOfShape& remFace,