allow wires as surface input
Now an arbitrary mixture of edges and wires can be used as input. However, the total count of edges together with the wire members can only be 2, 3 or 4. For some reason, wires do not work in Python script: test1.BoundaryList = [(Draft.upgrade([bs1a, bs2a]), 'Wire1')] yields an empty BoundaryList
This commit is contained in:
@@ -107,10 +107,9 @@ App::DocumentObjectExecReturn *BSplineSurf::execute(void)
|
||||
|
||||
GeomFill_FillingStyle fstyle = getFillingStyle();
|
||||
GeomFill_BSplineCurves aSurfBuilder; //Create Surface Builder
|
||||
int ncrv = BoundaryList.getSize();
|
||||
if(ncrv==2) {aSurfBuilder.Init(crvs[0], crvs[1], fstyle);}
|
||||
else if(ncrv==3) {aSurfBuilder.Init(crvs[0], crvs[1], crvs[2], fstyle);}
|
||||
else if(ncrv==4) {aSurfBuilder.Init(crvs[0], crvs[1], crvs[2], crvs[3], fstyle);}
|
||||
if(edgeCount==2) {aSurfBuilder.Init(crvs[0], crvs[1], fstyle);}
|
||||
else if(edgeCount==3) {aSurfBuilder.Init(crvs[0], crvs[1], crvs[2], fstyle);}
|
||||
else if(edgeCount==4) {aSurfBuilder.Init(crvs[0], crvs[1], crvs[2], crvs[3], fstyle);}
|
||||
|
||||
createFace(aSurfBuilder.Surface());
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <GeomFill_BezierCurves.hxx>
|
||||
#include <Geom_BoundedSurface.hxx>
|
||||
#include <BRepBuilderAPI_MakeFace.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#endif
|
||||
|
||||
#include <Base/Exception.h>
|
||||
@@ -82,43 +83,57 @@ void BSurf::getWire(TopoDS_Wire& aWire)
|
||||
Handle(ShapeExtend_WireData) aWD = new ShapeExtend_WireData;
|
||||
|
||||
int boundaryListSize = BoundaryList.getSize();
|
||||
if(boundaryListSize > 4 || boundaryListSize < 2)
|
||||
if(boundaryListSize > 4) // if too many not even try
|
||||
{
|
||||
Standard_Failure::Raise("Only 2-4 curves are allowed");
|
||||
return;
|
||||
}
|
||||
|
||||
BRepBuilderAPI_Copy copier;
|
||||
edgeCount = 0;
|
||||
for(int i = 0; i < boundaryListSize; i++)
|
||||
{
|
||||
Part::TopoShape ts; //Curve TopoShape
|
||||
TopoDS_Shape sub; //Curve TopoDS_Shape
|
||||
TopoDS_Edge etmp; //Curve TopoDS_Edge
|
||||
|
||||
//Get Edge
|
||||
App::PropertyLinkSubList::SubSet set = BoundaryList[i];
|
||||
|
||||
if(set.obj->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) {
|
||||
|
||||
ts = static_cast<Part::Feature*>(set.obj)->Shape.getShape();
|
||||
|
||||
//we want only the subshape which is linked
|
||||
sub = ts.getSubShape(set.sub);
|
||||
// make a copy of the shape and the underlying geometry to avoid to affect the input shapes
|
||||
BRepBuilderAPI_Copy copy(sub);
|
||||
sub = copy.Shape();
|
||||
|
||||
if(sub.ShapeType() == TopAbs_EDGE) { //Check Shape type and assign edge
|
||||
etmp = TopoDS::Edge(sub);
|
||||
const Part::TopoShape &ts = static_cast<Part::Feature*>(set.obj)->Shape.getShape();
|
||||
if(ts._Shape.ShapeType() == TopAbs_WIRE)
|
||||
{
|
||||
const TopoDS_Wire &wire = TopoDS::Wire(ts._Shape);
|
||||
// resolve the wire, we need edges from now on
|
||||
for (TopExp_Explorer wireExplorer (wire, TopAbs_EDGE); wireExplorer.More(); wireExplorer.Next())
|
||||
{
|
||||
// make a copy of the shape and the underlying geometry to avoid to affect the input shapes
|
||||
copier.Perform(wireExplorer.Current());
|
||||
aWD->Add(TopoDS::Edge(copier.Shape()));
|
||||
edgeCount++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Standard_Failure::Raise("Curves must be type TopoDS_Edge");
|
||||
return; //Raise exception
|
||||
}
|
||||
aWD->Add(etmp);
|
||||
else
|
||||
{
|
||||
//we want only the subshape which is linked
|
||||
const TopoDS_Shape &sub = ts.getSubShape(set.sub);
|
||||
// make a copy of the shape and the underlying geometry to avoid to affect the input shapes
|
||||
copier.Perform(sub);
|
||||
const TopoDS_Shape © = copier.Shape();
|
||||
|
||||
if(copy.ShapeType() == TopAbs_EDGE) { //Check Shape type and assign edge
|
||||
aWD->Add(TopoDS::Edge(copy));
|
||||
edgeCount++;
|
||||
}
|
||||
else {
|
||||
Standard_Failure::Raise("Curves must be of type TopoDS_Edge or TopoDS_Wire");
|
||||
return; //Raise exception
|
||||
}
|
||||
}
|
||||
}
|
||||
else{Standard_Failure::Raise("Curve not from Part::Feature");return;}
|
||||
|
||||
}
|
||||
if(edgeCount < 2 || edgeCount > 4)
|
||||
{
|
||||
Standard_Failure::Raise("Only 2-4 curves are allowed");
|
||||
return;
|
||||
}
|
||||
|
||||
//Reorder the curves and fix the wire if required
|
||||
|
||||
@@ -61,6 +61,9 @@ protected:
|
||||
// corrects the initially invalid fill type
|
||||
void correcteInvalidFillType();
|
||||
|
||||
// number of edges is a result of calculating single and wire edges
|
||||
int edgeCount;
|
||||
|
||||
private:
|
||||
static const char* FillTypeEnums[];
|
||||
};
|
||||
|
||||
@@ -89,10 +89,9 @@ App::DocumentObjectExecReturn *BezSurf::execute(void)
|
||||
|
||||
GeomFill_FillingStyle fstyle = getFillingStyle();
|
||||
GeomFill_BezierCurves aSurfBuilder; //Create Surface Builder
|
||||
int ncrv = BoundaryList.getSize();
|
||||
if(ncrv==2) {aSurfBuilder.Init(crvs[0], crvs[1], fstyle);}
|
||||
else if(ncrv==3) {aSurfBuilder.Init(crvs[0], crvs[1], crvs[2], fstyle);}
|
||||
else if(ncrv==4) {aSurfBuilder.Init(crvs[0], crvs[1], crvs[2], crvs[3], fstyle);}
|
||||
if(edgeCount==2) {aSurfBuilder.Init(crvs[0], crvs[1], fstyle);}
|
||||
else if(edgeCount==3) {aSurfBuilder.Init(crvs[0], crvs[1], crvs[2], fstyle);}
|
||||
else if(edgeCount==4) {aSurfBuilder.Init(crvs[0], crvs[1], crvs[2], crvs[3], fstyle);}
|
||||
|
||||
createFace(aSurfBuilder.Surface());
|
||||
|
||||
|
||||
@@ -160,6 +160,8 @@ public:
|
||||
protected:
|
||||
bool willBezier;
|
||||
bool willBSpline;
|
||||
int edgeCount;
|
||||
bool isEdge(const TopoDS_Shape& shape);
|
||||
virtual bool isActive(void);
|
||||
void createSurface(const char *surfaceNamePrefix, const char *commandName, const char *pythonAddCommand);
|
||||
virtual void activated(int iMsg);
|
||||
@@ -176,13 +178,51 @@ CmdSurfaceBSurf::CmdSurfaceBSurf() : Command("Surface_BSurf")
|
||||
sPixmap = "BSplineSurf";
|
||||
}
|
||||
|
||||
bool CmdSurfaceBSurf::isEdge(const TopoDS_Shape& shape)
|
||||
{
|
||||
if (shape.IsNull() || shape.ShapeType() != TopAbs_EDGE)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
TopoDS_Edge etmp = TopoDS::Edge(shape); //Curve TopoDS_Edge
|
||||
TopLoc_Location heloc; // this will be output
|
||||
Standard_Real u0;// contains output
|
||||
Standard_Real u1;// contains output
|
||||
Handle_Geom_Curve c_geom = BRep_Tool::Curve(etmp,heloc,u0,u1); //The geometric curve
|
||||
Handle_Geom_BezierCurve bez_geom = Handle_Geom_BezierCurve::DownCast(c_geom); //Try to get Bezier curve
|
||||
if (bez_geom.IsNull())
|
||||
{
|
||||
// this one is not Bezier, we hope it can be converted into b-spline
|
||||
if(willBezier) {
|
||||
// already found the other type, fail
|
||||
return false;
|
||||
}
|
||||
// we will create b-spline surface
|
||||
willBSpline = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// this one is Bezier
|
||||
if(willBSpline) {
|
||||
// already found the other type, fail
|
||||
return false;
|
||||
}
|
||||
// we will create Bezier surface
|
||||
willBezier = true;
|
||||
}
|
||||
edgeCount++;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CmdSurfaceBSurf::isActive(void)
|
||||
{
|
||||
willBezier = willBSpline = false;
|
||||
std::vector<Gui::SelectionSingleton::SelObj> Sel = getSelection().getSelection();
|
||||
if (Sel.size() < 2 || Sel.size() > 4) {
|
||||
if (Sel.size() > 4) {
|
||||
return false;
|
||||
}
|
||||
// we need to count them inside wires, too
|
||||
edgeCount = 0;
|
||||
for (std::vector<Gui::SelectionSingleton::SelObj>::iterator it = Sel.begin(); it != Sel.end(); ++it)
|
||||
{
|
||||
if(!((*it).pObject->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()))) {
|
||||
@@ -191,67 +231,57 @@ bool CmdSurfaceBSurf::isActive(void)
|
||||
Part::TopoShape ts = static_cast<Part::Feature*>((*it).pObject)->Shape.getShape();
|
||||
try {
|
||||
// make sure the main shape type is edge or wire
|
||||
TopAbs_ShapeEnum shapeType = ts._Shape.ShapeType();
|
||||
if(shapeType != TopAbs_WIRE && shapeType != TopAbs_EDGE)
|
||||
if(ts._Shape.ShapeType() == TopAbs_WIRE)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
TopoDS_Shape shape = ts.getSubShape("Edge1");
|
||||
if (shape.IsNull())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(shape.ShapeType() != TopAbs_EDGE) { //Check Shape type and assign edge
|
||||
return false;
|
||||
}
|
||||
TopoDS_Edge etmp = TopoDS::Edge(shape); //Curve TopoDS_Edge
|
||||
TopLoc_Location heloc; // this will be output
|
||||
Standard_Real u0;// contains output
|
||||
Standard_Real u1;// contains output
|
||||
Handle_Geom_Curve c_geom = BRep_Tool::Curve(etmp,heloc,u0,u1); //The geometric curve
|
||||
Handle_Geom_BezierCurve bez_geom = Handle_Geom_BezierCurve::DownCast(c_geom); //Try to get Bezier curve
|
||||
if (bez_geom.IsNull())
|
||||
{
|
||||
// this one is not Bezier, we hope it can be converted into b-spline
|
||||
if(willBezier) {
|
||||
// already found the other type, fail
|
||||
return false;
|
||||
TopoDS_Wire wire = TopoDS::Wire(ts._Shape);
|
||||
for (TopExp_Explorer wireExplorer (wire, TopAbs_EDGE); wireExplorer.More(); wireExplorer.Next())
|
||||
{
|
||||
if(!isEdge(wireExplorer.Current()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// we will create b-spline surface
|
||||
willBSpline = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// this one is Bezier
|
||||
if(willBSpline) {
|
||||
// already found the other type, fail
|
||||
TopoDS_Shape shape = ts.getSubShape("Edge1");
|
||||
if(!isEdge(shape))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// we will create Bezier surface
|
||||
willBezier = true;
|
||||
}
|
||||
}
|
||||
catch(Standard_Failure) { // any OCC exception means an unappropriate shape in the selection
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return edgeCount >= 2 && edgeCount <= 4;
|
||||
}
|
||||
|
||||
void CmdSurfaceBSurf::createSurface(const char *surfaceNamePrefix, const char *commandName, const char *pythonAddCommand)
|
||||
{
|
||||
// we take the whole selection and require that all of its members are of the required curve
|
||||
std::vector<Gui::SelectionObject> sel = getSelection().getSelectionEx(0);
|
||||
if (sel.size() == 2) {
|
||||
if (edgeCount == 2) {
|
||||
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Warning"),
|
||||
QObject::tr("Surfaces with two edges may fail for some fill types."));
|
||||
}
|
||||
|
||||
std::string FeatName = getUniqueObjectName(surfaceNamePrefix);
|
||||
std::stringstream bspListCmd;
|
||||
std::vector<Gui::SelectionSingleton::SelObj> Sel = getSelection().getSelection();
|
||||
bspListCmd << "FreeCAD.ActiveDocument.ActiveObject.BoundaryList = [";
|
||||
for (std::vector<Gui::SelectionObject>::iterator it = sel.begin(); it != sel.end(); ++it) {
|
||||
bspListCmd << "(App.activeDocument()." << it->getFeatName() << ", \'Edge1\'),";
|
||||
for (std::vector<Gui::SelectionSingleton::SelObj>::iterator it = Sel.begin(); it != Sel.end(); ++it)
|
||||
{
|
||||
Part::TopoShape ts = static_cast<Part::Feature*>((*it).pObject)->Shape.getShape();
|
||||
bspListCmd << "(App.activeDocument()." << it->FeatName;
|
||||
// if it is wire, add as wire
|
||||
if(ts._Shape.ShapeType() == TopAbs_WIRE)
|
||||
{
|
||||
bspListCmd << ", \'Wire1\'),";
|
||||
}
|
||||
else
|
||||
{
|
||||
bspListCmd << ", \'Edge1\'),";
|
||||
}
|
||||
}
|
||||
bspListCmd << "]";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user