#include <fstream>
#include <vector>
//OpenCascade include
#include <TopoDS_Shape.hxx>
#include <BRep_Builder.hxx>
#include <BRepTools.hxx>
#include <ShapeAnalysis.hxx>
#include <TopoDS.hxx>
#include <TopExp.hxx>
#include <BRepBuilderAPI_NurbsConvert.hxx>
#include <GeomConvert.hxx>
#include <Geom_BSplineSurface.hxx>
#include <TopExp_Explorer.hxx>
#include <BRepBuilderAPI_MakeWire.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <ShapeFix_Face.hxx>
#include "viewer.h"
using namespace std;
int main()
{
Viewer vout(50, 50, 500, 500);
TopoDS_Shape myshape;
BRep_Builder b;
std::ifstream is;
is.open("1");
BRepTools::Read(myshape, is, b);
is.close();
TopTools_IndexedMapOfShape wires_map;
TopoDS_Face faceo = TopoDS::Face(myshape);
TopoDS_Wire outer_wire = ShapeAnalysis::OuterWire(faceo);
TopExp::MapShapes(faceo, TopAbs_WIRE, wires_map);
BRepBuilderAPI_NurbsConvert nurbs_convert;
nurbs_convert = BRepBuilderAPI_NurbsConvert(faceo);
nurbs_convert.Perform(faceo);
TopoDS_Shape face_shape = nurbs_convert.Shape();
Handle(Geom_Surface) h_geomface = BRep_Tool::Surface(TopoDS::Face(face_shape));
Handle(Geom_BSplineSurface)h_bsurface = GeomConvert::SurfaceToBSplineSurface(h_geomface);
std::vector<TopoDS_Wire> inner_wires;
for (int j = 1; j <= wires_map.Extent(); j++)
{
if (!wires_map(j).IsSame(outer_wire))
{
inner_wires.push_back(TopoDS::Wire(wires_map(j)));
}
}
std::vector<std::vector<Standard_Real>> parameter;
std::vector<std::vector<Standard_Real>> parameter2;
std::vector<Handle(Geom2d_Curve)> p_curve1;
std::vector<Handle(Geom2d_Curve)> p_curve2;
TopExp_Explorer edge_exp;
Standard_Boolean flag;
for (edge_exp.Init(outer_wire, TopAbs_EDGE); edge_exp.More(); edge_exp.Next()) {
TopoDS_Edge edge = TopoDS::Edge(edge_exp.Current().Composed(outer_wire.Orientation()));
Standard_Real first;
Standard_Real last;
Handle(Geom2d_Curve) my_handle = BRep_Tool::CurveOnSurface(edge, faceo, first, last, &flag);
parameter.push_back(std::vector<Standard_Real>{first, last});
p_curve1.push_back(my_handle);
}
for (auto inwire : inner_wires) {
TopExp_Explorer edge_exp2;
Standard_Boolean flag2;
for (edge_exp2.Init(inwire, TopAbs_EDGE); edge_exp2.More(); edge_exp2.Next()) {
TopoDS_Edge edge = TopoDS::Edge(edge_exp2.Current().Composed(inwire.Orientation()));
Standard_Real first;
Standard_Real last;
p_curve2.push_back(BRep_Tool::CurveOnSurface(edge, faceo, first, last, &flag2));
parameter2.push_back(std::vector<Standard_Real>{first, last});
}
}
BRepBuilderAPI_MakeWire mkWire;
int i = 0;
for (auto a : p_curve1) {
TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge(a, h_bsurface, parameter[i][0], parameter[i][1]);
i++;
//vout << anEdge;
mkWire.Add(anEdge);
}
TopoDS_Wire new_wire = mkWire.Wire();
BRepBuilderAPI_MakeFace faceMaker(h_bsurface, new_wire, false);
new_wire.Reverse();
if (p_curve2.size() != 0) {
BRepBuilderAPI_MakeWire mkWire2;
for (int j = 0; j < p_curve2.size(); j++) {
TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge(p_curve2[j], h_bsurface, parameter2[j][0], parameter2[j][1]);
mkWire2.Add(anEdge);
}
TopoDS_Wire new_wire2 = mkWire2.Wire();
faceMaker.Add(new_wire2);
}
ShapeFix_Face fix(faceMaker.Face());
fix.SetPrecision(1e-7);
fix.Perform();
if (fix.Status(ShapeExtend_OK))
cout << "ShapeExtend_OK ";
else if (fix.Status(ShapeExtend_DONE1))
cout << "ShapeExtend_DONE1";
else if (fix.Status(ShapeExtend_DONE2))
cout << "ShapeExtend_DONE2";
else if (fix.Status(ShapeExtend_DONE3))
cout << "ShapeExtend_DONE3";
else if (fix.Status(ShapeExtend_DONE4))
cout << "ShapeExtend_DONE4";
else if (fix.Status(ShapeExtend_DONE5))
cout << "ShapeExtend_DONE5";
else if (fix.Status(ShapeExtend_DONE6))
cout << "ShapeExtend_DONE6";
else if (fix.Status(ShapeExtend_DONE7))
cout << "ShapeExtend_DONE7";
else if (fix.Status(ShapeExtend_DONE8))
cout << "ShapeExtend_DONE8";
else if (fix.Status(ShapeExtend_DONE))
cout << "ShapeExtend_DONE ";
else if (fix.Status(ShapeExtend_FAIL1))
cout << "ShapeExtend_FAIL1 ";
else if (fix.Status(ShapeExtend_FAIL2))
cout << "ShapeExtend_FAIL2 ";
else if (fix.Status(ShapeExtend_FAIL3))
cout << "ShapeExtend_FAIL3 ";
else if (fix.Status(ShapeExtend_FAIL4))
cout << "ShapeExtend_FAIL4 ";
else if (fix.Status(ShapeExtend_FAIL5))
cout << "ShapeExtend_FAIL5 ";
else if (fix.Status(ShapeExtend_FAIL6))
cout << "ShapeExtend_FAIL6 ";
else if (fix.Status(ShapeExtend_FAIL7))
cout << "ShapeExtend_FAIL7 ";
else if (fix.Status(ShapeExtend_FAIL8))
cout << "ShapeExtend_FAIL8 ";
else if (fix.Status(ShapeExtend_FAIL))
cout << "ShapeExtend_FAIL ";
vout << fix.Face();
vout.StartMessageLoop();
}