Improve ruled surface feature

This commit is contained in:
wmayer 2013-05-25 16:58:20 +02:00
parent fad26c93a5
commit d07fc16268
2 changed files with 70 additions and 0 deletions

View File

@ -24,6 +24,10 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <BRepFill.hxx>
# include <BRepAdaptor_Curve.hxx>
# include <BRepAdaptor_HCurve.hxx>
# include <BRepAdaptor_CompCurve.hxx>
# include <BRepAdaptor_HCompCurve.hxx>
# include <TopoDS.hxx>
# include <TopoDS_Face.hxx>
# include <TopoDS_Shell.hxx>
@ -32,7 +36,9 @@
# include <ShapeAnalysis.hxx>
# include <TopTools_ListIteratorOfListOfShape.hxx>
# include <TopExp_Explorer.hxx>
# include <TopoDS.hxx>
# include <Precision.hxx>
# include <Handle_Adaptor3d_HCurve.hxx>
#endif
@ -43,10 +49,14 @@ using namespace Part;
PROPERTY_SOURCE(Part::RuledSurface, Part::Feature)
const char* RuledSurface::OrientationEnums[] = {"Automatic","Forward","Reversed",NULL};
RuledSurface::RuledSurface()
{
ADD_PROPERTY_TYPE(Curve1,(0),"Ruled Surface",App::Prop_None,"Curve of ruled surface");
ADD_PROPERTY_TYPE(Curve2,(0),"Ruled Surface",App::Prop_None,"Curve of ruled surface");
ADD_PROPERTY_TYPE(Orientation,((long)0),"Ruled Surface",App::Prop_None,"Orientation of ruled surface");
Orientation.setEnums(OrientationEnums);
}
short RuledSurface::mustExecute() const
@ -55,6 +65,8 @@ short RuledSurface::mustExecute() const
return 1;
if (Curve2.isTouched())
return 1;
if (Orientation.isTouched())
return 1;
return 0;
}
@ -109,6 +121,60 @@ App::DocumentObjectExecReturn *RuledSurface::execute(void)
if (curve1.IsNull() || curve2.IsNull())
return new App::DocumentObjectExecReturn("Linked shapes are empty.");
if (Orientation.getValue() == 0) {
// Automatic
Handle_Adaptor3d_HCurve a1;
Handle_Adaptor3d_HCurve a2;
if (curve1.ShapeType() == TopAbs_EDGE && curve2.ShapeType() == TopAbs_EDGE) {
BRepAdaptor_Curve adapt1(TopoDS::Edge(curve1));
BRepAdaptor_Curve adapt2(TopoDS::Edge(curve2));
a1 = new BRepAdaptor_HCurve(adapt1);
a2 = new BRepAdaptor_HCurve(adapt2);
}
else if (curve1.ShapeType() == TopAbs_WIRE && curve2.ShapeType() == TopAbs_WIRE) {
BRepAdaptor_CompCurve adapt1(TopoDS::Wire(curve1));
BRepAdaptor_CompCurve adapt2(TopoDS::Wire(curve2));
a1 = new BRepAdaptor_HCompCurve(adapt1);
a2 = new BRepAdaptor_HCompCurve(adapt2);
}
if (!a1.IsNull() && !a2.IsNull()) {
// get end points of 1st curve
gp_Pnt p1 = a1->Value(a1->FirstParameter());
gp_Pnt p2 = a1->Value(a1->LastParameter());
if (curve1.Orientation() == TopAbs_REVERSED) {
std::swap(p1, p2);
}
// get end points of 2nd curve
gp_Pnt p3 = a2->Value(a2->FirstParameter());
gp_Pnt p4 = a2->Value(a2->LastParameter());
if (curve2.Orientation() == TopAbs_REVERSED) {
std::swap(p3, p4);
}
// Form two triangles (P1,P2,P3) and (P4,P3,P2) and check their normals.
// If the dot product is negative then it's assumed that the resulting face
// is twisted, hence the 2nd edge is reversed.
gp_Vec v1(p1, p2);
gp_Vec v2(p1, p3);
gp_Vec n1 = v1.Crossed(v2);
gp_Vec v3(p4, p3);
gp_Vec v4(p4, p2);
gp_Vec n2 = v3.Crossed(v4);
if (n1.Dot(n2) < 0) {
curve2.Reverse();
}
}
}
else if (Orientation.getValue() == 2) {
// Reverse
curve2.Reverse();
}
if (curve1.ShapeType() == TopAbs_EDGE && curve2.ShapeType() == TopAbs_EDGE) {
TopoDS_Face face = BRepFill::Face(TopoDS::Edge(curve1), TopoDS::Edge(curve2));
this->Shape.setValue(face);

View File

@ -38,6 +38,7 @@ class RuledSurface : public Part::Feature
public:
RuledSurface();
App::PropertyEnumeration Orientation;
App::PropertyLinkSub Curve1;
App::PropertyLinkSub Curve2;
@ -53,6 +54,9 @@ public:
protected:
void onChanged (const App::Property* prop);
private:
static const char* OrientationEnums[];
};
class Loft : public Part::Feature