Allow datum points and lines to have offsets from their references
This commit is contained in:
parent
22e3aaa2d6
commit
b6932b0bdb
|
@ -74,6 +74,8 @@ Datum::Datum(void)
|
|||
{
|
||||
ADD_PROPERTY_TYPE(References,(0,0),"References",(App::PropertyType)(App::Prop_None),"References defining the datum feature");
|
||||
ADD_PROPERTY(Offset,(0.0));
|
||||
ADD_PROPERTY(Offset2,(0.0));
|
||||
ADD_PROPERTY(Offset3,(0.0));
|
||||
ADD_PROPERTY(Angle,(0.0));
|
||||
touch();
|
||||
}
|
||||
|
|
|
@ -42,11 +42,14 @@ class PartExport Datum : public Part::Feature
|
|||
public:
|
||||
Datum();
|
||||
virtual ~Datum();
|
||||
//short mustExecute();
|
||||
|
||||
/// The references defining the datum object, e.g. three planes for a point, two planes for a line
|
||||
App::PropertyLinkSubList References;
|
||||
/// Offset and angle for defining planes
|
||||
/// Offsets and angle for defining planes
|
||||
App::PropertyFloat Offset;
|
||||
App::PropertyFloat Offset2;
|
||||
App::PropertyFloat Offset3;
|
||||
App::PropertyFloat Angle;
|
||||
|
||||
/// recalculate the feature
|
||||
|
@ -55,7 +58,10 @@ public:
|
|||
/// returns the type name of the view provider
|
||||
virtual const char* getViewProviderName(void) const = 0;
|
||||
|
||||
virtual const std::set<QString> getHint() = 0;
|
||||
virtual const std::set<QString> getHint() const = 0;
|
||||
|
||||
/// Return the number of offset values that make sense for the current reference combination
|
||||
virtual const int offsetsAllowed() const = 0;
|
||||
|
||||
/// Return a shape including Placement representing the datum feature
|
||||
TopoDS_Shape getShape() const;
|
||||
|
|
|
@ -32,15 +32,20 @@
|
|||
# include <BRepBuilderAPI_GTransform.hxx>
|
||||
# include <BRep_Tool.hxx>
|
||||
# include <gp_GTrsf.hxx>
|
||||
# include <gp_Ax3.hxx>
|
||||
# include <gp_Lin.hxx>
|
||||
# include <gp_Pln.hxx>
|
||||
# include <gp_Circ.hxx>
|
||||
# include <gp_Cylinder.hxx>
|
||||
# include <Geom_Line.hxx>
|
||||
# include <Geom_Plane.hxx>
|
||||
# include <Geom_CylindricalSurface.hxx>
|
||||
# include <Geom2d_Line.hxx>
|
||||
# include <Handle_Geom_Curve.hxx>
|
||||
# include <Handle_Geom_Surface.hxx>
|
||||
# include <Handle_Geom_Plane.hxx>
|
||||
# include <Handle_Geom2d_Line.hxx>
|
||||
# include <Handle_Standard_Type.hxx>
|
||||
# include <GeomAPI_IntCS.hxx>
|
||||
# include <GeomAPI_IntSS.hxx>
|
||||
# include <GeomAPI_ExtremaCurveCurve.hxx>
|
||||
|
@ -101,12 +106,22 @@ void Line::initHints()
|
|||
key.clear(); value.clear();
|
||||
key.insert(PLANE);
|
||||
value.insert(PLANE);
|
||||
hints[key] = value; // PLANE -> PLANE
|
||||
value.insert(LINE);
|
||||
hints[key] = value; // PLANE -> LINE or PLANE
|
||||
|
||||
key.clear(); value.clear();
|
||||
key.insert(PLANE); key.insert(PLANE);
|
||||
hints[key] = DONE; // {PLANE, PLANE} -> DONE. Line from two planes or faces
|
||||
|
||||
key.clear(); value.clear();
|
||||
key.insert(PLANE); key.insert(LINE);
|
||||
value.insert(LINE);
|
||||
hints[key] = value; // {PLANE, LINE} -> LINE
|
||||
|
||||
key.clear(); value.clear();
|
||||
key.insert(PLANE); key.insert(LINE); key.insert(LINE);
|
||||
hints[key] = DONE; // {PLANE, LINE, LINE} -> DONE. Line from plane with distance (default zero) to two lines
|
||||
|
||||
key.clear(); value.clear();
|
||||
value.insert(POINT); value.insert(LINE); value.insert(PLANE);
|
||||
hints[key] = value;
|
||||
|
@ -132,10 +147,12 @@ Line::~Line()
|
|||
|
||||
void Line::onChanged(const App::Property *prop)
|
||||
{
|
||||
if (prop == &References) {
|
||||
if ((prop == &References) || (prop == &Offset) || (prop == &Offset2)) {
|
||||
refTypes.clear();
|
||||
std::vector<App::DocumentObject*> refs = References.getValues();
|
||||
std::vector<std::string> refnames = References.getSubValues();
|
||||
if (refs.size() != refnames.size())
|
||||
return;
|
||||
|
||||
for (int r = 0; r < refs.size(); r++)
|
||||
refTypes.insert(getRefType(refs[r], refnames[r]));
|
||||
|
@ -152,6 +169,7 @@ void Line::onChanged(const App::Property *prop)
|
|||
gp_Lin* line = NULL;
|
||||
Handle_Geom_Surface s1 = NULL;
|
||||
Handle_Geom_Surface s2 = NULL;
|
||||
Handle_Geom_Surface s3 = NULL;
|
||||
|
||||
for (int i = 0; i < refs.size(); i++) {
|
||||
if (refs[i]->getTypeId().isDerivedFrom(PartDesign::Point::getClassTypeId())) {
|
||||
|
@ -162,16 +180,41 @@ void Line::onChanged(const App::Property *prop)
|
|||
p2 = new Base::Vector3d (p->getPoint());
|
||||
} else if (refs[i]->getTypeId().isDerivedFrom(PartDesign::Line::getClassTypeId())) {
|
||||
PartDesign::Line* l = static_cast<PartDesign::Line*>(refs[i]);
|
||||
base = new Base::Vector3d (l->getBasePoint());
|
||||
direction = new Base::Vector3d (l->getDirection());
|
||||
if (s1.IsNull()) {
|
||||
base = new Base::Vector3d (l->getBasePoint());
|
||||
direction = new Base::Vector3d (l->getDirection());
|
||||
} else {
|
||||
// Create plane through line normal to s1
|
||||
Handle_Geom_Plane pl = Handle_Geom_Plane::DownCast(s1);
|
||||
if (pl.IsNull())
|
||||
return; // Non-planar first surface
|
||||
gp_Dir ldir = gp_Dir(l->getDirection().x, l->getDirection().y, l->getDirection().z);
|
||||
gp_Dir normal = ldir.Crossed(pl->Axis().Direction());
|
||||
double offset1 = Offset.getValue();
|
||||
double offset2 = Offset2.getValue();
|
||||
gp_Pnt base = gp_Pnt(l->getBasePoint().x, l->getBasePoint().y, l->getBasePoint().z);
|
||||
if (s2.IsNull()) {
|
||||
base.Translate(offset1 * normal);
|
||||
s2 = new Geom_Plane(base, normal);
|
||||
} else {
|
||||
base.Translate(offset2 * normal);
|
||||
s3 = new Geom_Plane(base, normal);
|
||||
}
|
||||
}
|
||||
} else if (refs[i]->getTypeId().isDerivedFrom(PartDesign::Plane::getClassTypeId())) {
|
||||
PartDesign::Plane* p = static_cast<PartDesign::Plane*>(refs[i]);
|
||||
Base::Vector3d base = p->getBasePoint();
|
||||
Base::Vector3d normal = p->getNormal();
|
||||
if (s1.IsNull())
|
||||
double offset1 = Offset.getValue();
|
||||
double offset2 = Offset2.getValue();
|
||||
|
||||
if (s1.IsNull()) {
|
||||
base += normal * offset1;
|
||||
s1 = new Geom_Plane(gp_Pnt(base.x, base.y, base.z), gp_Dir(normal.x, normal.y, normal.z));
|
||||
else
|
||||
} else {
|
||||
base += normal * offset2;
|
||||
s2 = new Geom_Plane(gp_Pnt(base.x, base.y, base.z), gp_Dir(normal.x, normal.y, normal.z));
|
||||
}
|
||||
} else if (refs[i]->getTypeId().isDerivedFrom(App::Plane::getClassTypeId())) {
|
||||
App::Plane* p = static_cast<App::Plane*>(refs[i]);
|
||||
// Note: We only handle the three base planes here
|
||||
|
@ -184,10 +227,16 @@ void Line::onChanged(const App::Property *prop)
|
|||
else if (strcmp(p->getNameInDocument(), "BaseplaneXZ") == 0)
|
||||
normal = gp_Dir(0,1,0);
|
||||
|
||||
if (s1.IsNull())
|
||||
double offset1 = Offset.getValue();
|
||||
double offset2 = Offset2.getValue();
|
||||
|
||||
if (s1.IsNull()) {
|
||||
base = gp_Pnt(normal.X() * offset1, normal.Y() * offset1, normal.Z() * offset1);
|
||||
s1 = new Geom_Plane(base, normal);
|
||||
else
|
||||
} else {
|
||||
base = gp_Pnt(normal.X() * offset2, normal.Y() * offset2, normal.Z() * offset2);
|
||||
s2 = new Geom_Plane(base, normal);
|
||||
}
|
||||
} else if (refs[i]->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) {
|
||||
Part::Feature* feature = static_cast<Part::Feature*>(refs[i]);
|
||||
const TopoDS_Shape& sh = feature->Shape.getValue();
|
||||
|
@ -208,15 +257,57 @@ void Line::onChanged(const App::Property *prop)
|
|||
} else if (subshape.ShapeType() == TopAbs_EDGE) {
|
||||
TopoDS_Edge e = TopoDS::Edge(subshape);
|
||||
BRepAdaptor_Curve adapt(e);
|
||||
if (adapt.GetType() != GeomAbs_Line)
|
||||
if (adapt.GetType() == GeomAbs_Circle) {
|
||||
circle = new gp_Circ(adapt.Circle());
|
||||
} else if (adapt.GetType() == GeomAbs_Line) {
|
||||
if (s1.IsNull()) {
|
||||
line = new gp_Lin(adapt.Line());
|
||||
} else {
|
||||
// Create plane through line normal to s1
|
||||
Handle_Geom_Plane pl = Handle_Geom_Plane::DownCast(s1);
|
||||
if (pl.IsNull())
|
||||
return; // Non-planar first surface
|
||||
gp_Dir normal = adapt.Line().Direction().Crossed(pl->Axis().Direction());
|
||||
double offset1 = Offset.getValue();
|
||||
double offset2 = Offset2.getValue();
|
||||
gp_Pnt base = adapt.Line().Location();
|
||||
if (s2.IsNull()) {
|
||||
base.Translate(offset1 * normal);
|
||||
s2 = new Geom_Plane(base, normal);
|
||||
} else {
|
||||
base.Translate(offset2 * normal);
|
||||
s3 = new Geom_Plane(base, normal);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return; // Non-linear edge
|
||||
line = new gp_Lin(adapt.Line());
|
||||
}
|
||||
} else if (subshape.ShapeType() == TopAbs_FACE) {
|
||||
TopoDS_Face f = TopoDS::Face(subshape);
|
||||
if (s1.IsNull())
|
||||
double offset1 = Offset.getValue();
|
||||
double offset2 = Offset2.getValue();
|
||||
BRepAdaptor_Surface adapt(f);
|
||||
|
||||
if (s1.IsNull()) {
|
||||
if (adapt.GetType() == GeomAbs_Cylinder) {
|
||||
circle = new gp_Circ(gp_Ax2(adapt.Cylinder().Location(), adapt.Cylinder().Axis().Direction()),
|
||||
adapt.Cylinder().Radius());
|
||||
} else if (adapt.GetType() == GeomAbs_Plane) {
|
||||
gp_Trsf mov;
|
||||
mov.SetTranslation(offset1 * gp_Vec(adapt.Plane().Axis().Direction()));
|
||||
TopLoc_Location loc(mov);
|
||||
f.Move(loc);
|
||||
}
|
||||
s1 = BRep_Tool::Surface(f);
|
||||
else
|
||||
} else {
|
||||
if (adapt.GetType() == GeomAbs_Plane) {
|
||||
gp_Trsf mov;
|
||||
mov.SetTranslation(offset2 * gp_Vec(adapt.Plane().Axis().Direction()));
|
||||
TopLoc_Location loc(mov);
|
||||
f.Move(loc);
|
||||
}
|
||||
s2 = BRep_Tool::Surface(f);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return; //"PartDesign::Point: Invalid reference type"
|
||||
|
@ -233,12 +324,21 @@ void Line::onChanged(const App::Property *prop)
|
|||
// Line from gp_lin
|
||||
base = new Base::Vector3d(line->Location().X(), line->Location().Y(), line->Location().Z());
|
||||
direction = new Base::Vector3d(line->Direction().X(), line->Direction().Y(), line->Direction().Z());
|
||||
} else if (!s1.IsNull() && !s2.IsNull()) {
|
||||
} else if (circle != NULL) {
|
||||
// Line from center of circle or cylinder
|
||||
gp_Pnt centre = circle->Axis().Location();
|
||||
base = new Base::Vector3d(centre.X(), centre.Y(), centre.Z());
|
||||
gp_Dir dir = circle->Axis().Direction();
|
||||
direction = new Base::Vector3d(dir.X(), dir.Y(), dir.Z());
|
||||
} else if (!s1.IsNull() && !s2.IsNull()) {
|
||||
if (!s3.IsNull())
|
||||
s1 = s3; // Line from a plane and two lines/edges
|
||||
// Line from two surfaces
|
||||
GeomAPI_IntSS intersectorSS(s1, s2, Precision::Confusion());
|
||||
if (!intersectorSS.IsDone() || (intersectorSS.NbLines() == 0))
|
||||
return;
|
||||
if (intersectorSS.NbLines() > 1)
|
||||
Base::Console().Warning("More than one intersection line for datum point from surfaces");
|
||||
Base::Console().Warning("More than one intersection curve for datum line from surfaces\n");
|
||||
Handle_Geom_Line l = Handle_Geom_Line::DownCast(intersectorSS.Line(1));
|
||||
if (l.IsNull())
|
||||
return; // non-linear intersection curve
|
||||
|
@ -269,6 +369,19 @@ const std::set<QString> Line::getHint()
|
|||
return std::set<QString>();
|
||||
}
|
||||
|
||||
const int Line::offsetsAllowed() const
|
||||
{
|
||||
int planes = 0;
|
||||
int lines = 0;
|
||||
for (std::multiset<QString>::const_iterator r = refTypes.begin(); r != refTypes.end(); r++) {
|
||||
if (*r == PLANE) planes++;
|
||||
if (*r == LINE) lines++;
|
||||
}
|
||||
if (lines == 0) return planes;
|
||||
if ((planes == 1) && (lines == 2)) return 2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Base::Vector3d Line::getBasePoint() const
|
||||
{
|
||||
return Placement.getValue().getPosition();
|
||||
|
|
|
@ -179,7 +179,7 @@ void Plane::onChanged(const App::Property *prop)
|
|||
refTypes.erase(ANGLE);
|
||||
}
|
||||
|
||||
if (prop == &References) {
|
||||
if ((prop == &References) || (prop == &Offset)) {
|
||||
refTypes.clear();
|
||||
std::vector<App::DocumentObject*> refs = References.getValues();
|
||||
std::vector<std::string> refnames = References.getSubValues();
|
||||
|
@ -315,11 +315,11 @@ void Plane::onChanged(const App::Property *prop)
|
|||
if (!intersector.IsDone() || (intersector.NbPoints() == 0))
|
||||
return;
|
||||
if (intersector.NbPoints() > 1)
|
||||
Base::Console().Warning("More than one intersection point for datum plane from cylinder and plane");
|
||||
Base::Console().Warning("More than one intersection point for datum plane from cylinder and plane\n");
|
||||
|
||||
gp_Pnt inter = intersector.Point(1);
|
||||
p1 = new Base::Vector3d(inter.X(), inter.Y(), inter.Z());
|
||||
// TODO: Allow to control which side of the cylinder the plane is create on - there are always two possibilities
|
||||
// TODO: Allow to control which side of the cylinder the plane is created on - there are always two possibilities
|
||||
} else if ((p1 != NULL) && (normal != NULL)) {
|
||||
// plane from other plane. Nothing to be done
|
||||
} else if ((p1 != NULL) && (p2 != NULL) && (p3 != NULL)) {
|
||||
|
@ -366,6 +366,11 @@ const std::set<QString> Plane::getHint()
|
|||
return std::set<QString>();
|
||||
}
|
||||
|
||||
const int Plane::offsetsAllowed() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
Base::Vector3d Plane::getBasePoint()
|
||||
{
|
||||
return Placement.getValue().getPosition();
|
||||
|
|
|
@ -147,7 +147,7 @@ Point::~Point()
|
|||
|
||||
void Point::onChanged(const App::Property* prop)
|
||||
{
|
||||
if (prop == &References) {
|
||||
if ((prop == &References) || (prop == &Offset) || (prop == &Offset2) || (prop == &Offset3)) {
|
||||
refTypes.clear();
|
||||
std::vector<App::DocumentObject*> refs = References.getValues();
|
||||
std::vector<std::string> refnames = References.getSubValues();
|
||||
|
@ -230,12 +230,36 @@ void Point::onChanged(const App::Property* prop)
|
|||
c2 = BRep_Tool::Curve(e, first, last);
|
||||
} else if (subshape.ShapeType() == TopAbs_FACE) {
|
||||
TopoDS_Face f = TopoDS::Face(subshape);
|
||||
if (s1.IsNull())
|
||||
double offset1 = Offset.getValue();
|
||||
double offset2 = Offset2.getValue();
|
||||
double offset3 = Offset3.getValue();
|
||||
BRepAdaptor_Surface adapt(f);
|
||||
|
||||
if (s1.IsNull()) {
|
||||
if (adapt.GetType() == GeomAbs_Plane) {
|
||||
gp_Trsf mov;
|
||||
mov.SetTranslation(offset1 * gp_Vec(adapt.Plane().Axis().Direction()));
|
||||
TopLoc_Location loc(mov);
|
||||
f.Move(loc);
|
||||
}
|
||||
s1 = BRep_Tool::Surface(f);
|
||||
else if (s2.IsNull())
|
||||
} else if (s2.IsNull()) {
|
||||
if (adapt.GetType() == GeomAbs_Plane) {
|
||||
gp_Trsf mov;
|
||||
mov.SetTranslation(offset2 * gp_Vec(adapt.Plane().Axis().Direction()));
|
||||
TopLoc_Location loc(mov);
|
||||
f.Move(loc);
|
||||
}
|
||||
s2 = BRep_Tool::Surface(f);
|
||||
else
|
||||
} else {
|
||||
if (adapt.GetType() == GeomAbs_Plane) {
|
||||
gp_Trsf mov;
|
||||
mov.SetTranslation(offset3 * gp_Vec(adapt.Plane().Axis().Direction()));
|
||||
TopLoc_Location loc(mov);
|
||||
f.Move(loc);
|
||||
}
|
||||
s3 = BRep_Tool::Surface(f);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return; //"PartDesign::Point: Invalid reference type"
|
||||
|
@ -244,22 +268,47 @@ void Point::onChanged(const App::Property* prop)
|
|||
|
||||
if (point != NULL) {
|
||||
// Point from vertex or other point. Nothing to be done
|
||||
} else if (circle != NULL) {
|
||||
// Point from center of circle (or arc)
|
||||
gp_Pnt centre = circle->Axis().Location();
|
||||
point = new Base::Vector3d(centre.X(), centre.Y(), centre.Z());
|
||||
} else if (!c1.IsNull()) {
|
||||
if (!c2.IsNull()) {
|
||||
// Point from intersection of two curves
|
||||
// Point from intersection of two curves
|
||||
GeomAPI_ExtremaCurveCurve intersector(c1, c2);
|
||||
if ((intersector.LowerDistance() > Precision::Confusion()) || (intersector.NbExtrema() == 0))
|
||||
return; // No intersection
|
||||
// Note: We don't check for multiple intersection points
|
||||
gp_Pnt p, p2;
|
||||
intersector.Points(1, p, p2);
|
||||
|
||||
// Apply offset if the curves are linear (meaning they define a plane that contains them both)
|
||||
if ((c1->DynamicType() == STANDARD_TYPE(Geom_Line)) && (c2->DynamicType() == STANDARD_TYPE(Geom_Line))) {
|
||||
// Get translation vectors
|
||||
Handle_Geom_Line lin1 = Handle_Geom_Line::DownCast(c1);
|
||||
Handle_Geom_Line lin2 = Handle_Geom_Line::DownCast(c2);
|
||||
gp_Dir normal = lin1->Lin().Direction().Crossed(lin2->Lin().Direction()); // normal of the plane
|
||||
gp_Dir trans1 = normal.Crossed(lin1->Lin().Direction());
|
||||
gp_Dir trans2 = normal.Crossed(lin2->Lin().Direction());
|
||||
double offset1 = Offset.getValue();
|
||||
double offset2 = Offset2.getValue();
|
||||
c1->Translate(offset1 * gp_Vec(trans1));
|
||||
c2->Translate(offset2 * gp_Vec(trans2));
|
||||
// Intersect again
|
||||
intersector = GeomAPI_ExtremaCurveCurve(c1, c2);
|
||||
if ((intersector.LowerDistance() > Precision::Confusion()) || (intersector.NbExtrema() == 0))
|
||||
return; // No intersection
|
||||
// Note: We don't check for multiple intersection points
|
||||
intersector.Points(1, p, p2);
|
||||
}
|
||||
|
||||
point = new Base::Vector3d(p.X(), p.Y(), p.Z());
|
||||
} else if (!s1.IsNull()) {
|
||||
GeomAPI_IntCS intersector(c1, s1);
|
||||
if (!intersector.IsDone() || (intersector.NbPoints() == 0))
|
||||
return;
|
||||
if (intersector.NbPoints() > 1)
|
||||
Base::Console().Warning("More than one intersection point for datum point from curve and surface");
|
||||
Base::Console().Warning("More than one intersection point for datum point from curve and surface\n");
|
||||
|
||||
gp_Pnt p = intersector.Point(1);
|
||||
point = new Base::Vector3d(p.X(), p.Y(), p.Z());
|
||||
|
@ -270,14 +319,14 @@ void Point::onChanged(const App::Property* prop)
|
|||
if (!intersectorSS.IsDone() || (intersectorSS.NbLines() == 0))
|
||||
return;
|
||||
if (intersectorSS.NbLines() > 1)
|
||||
Base::Console().Warning("More than one intersection line for datum point from surfaces");
|
||||
Base::Console().Warning("More than one intersection line for datum point from surfaces\n");
|
||||
Handle_Geom_Curve line = intersectorSS.Line(1);
|
||||
|
||||
GeomAPI_IntCS intersector(line, s3);
|
||||
if (!intersector.IsDone() || (intersector.NbPoints() == 0))
|
||||
return;
|
||||
if (intersector.NbPoints() > 1)
|
||||
Base::Console().Warning("More than one intersection point for datum point from surfaces");
|
||||
Base::Console().Warning("More than one intersection point for datum point from surfaces\n");
|
||||
|
||||
gp_Pnt p = intersector.Point(1);
|
||||
point = new Base::Vector3d(p.X(), p.Y(), p.Z());
|
||||
|
@ -307,6 +356,19 @@ const std::set<QString> Point::getHint()
|
|||
return std::set<QString>();
|
||||
}
|
||||
|
||||
const int Point::offsetsAllowed() const
|
||||
{
|
||||
int numlines = 0, numplanes = 0;
|
||||
for (std::multiset<QString>::const_iterator r = refTypes.begin(); r != refTypes.end(); r++) {
|
||||
if (*r == LINE) numlines++;
|
||||
else if (*r == PLANE) numplanes++;
|
||||
}
|
||||
|
||||
if (numlines == 2) return 2; // Special case: Two intersecting lines. TODO: Check for co-planarity
|
||||
return numplanes;
|
||||
}
|
||||
|
||||
|
||||
namespace PartDesign {
|
||||
|
||||
const QString getRefType(const App::DocumentObject* obj, const std::string& subname)
|
||||
|
@ -320,13 +382,16 @@ const QString getRefType(const App::DocumentObject* obj, const std::string& subn
|
|||
else if (type == PartDesign::Point::getClassTypeId())
|
||||
return POINT;
|
||||
else if (type.isDerivedFrom(Part::Feature::getClassTypeId())) {
|
||||
if (subname.size() > 4 && subname.substr(0,4) == "Face") {
|
||||
const Part::Feature* feature = static_cast<const Part::Feature*>(obj);
|
||||
Part::TopoShape topShape = feature->Shape.getShape();
|
||||
TopoDS_Shape shape = topShape.getSubShape(subname.c_str());
|
||||
if (shape.IsNull() || (shape.ShapeType() != TopAbs_FACE))
|
||||
const Part::Feature* feature = static_cast<const Part::Feature*>(obj);
|
||||
const Part::TopoShape& topShape = feature->Shape.getShape();
|
||||
if (topShape.isNull())
|
||||
return QString::fromAscii("EMPTYSHAPE"); // Can happen on file loading
|
||||
|
||||
if (subname.size() > 4 && subname.substr(0,4) == "Face") {
|
||||
TopoDS_Shape face = topShape.getSubShape(subname.c_str());
|
||||
if (face.IsNull() || (face.ShapeType() != TopAbs_FACE))
|
||||
throw Base::Exception("Part::Datum::getRefType(): No valid subshape could be extracted");
|
||||
BRepAdaptor_Surface adapt(TopoDS::Face(shape));
|
||||
BRepAdaptor_Surface adapt(TopoDS::Face(face));
|
||||
if (adapt.GetType() == GeomAbs_Plane)
|
||||
return PLANE;
|
||||
else if (adapt.GetType() == GeomAbs_Cylinder)
|
||||
|
|
|
@ -108,6 +108,10 @@ TaskDatumParameters::TaskDatumParameters(ViewProviderDatum *DatumView,QWidget *p
|
|||
|
||||
connect(ui->spinOffset, SIGNAL(valueChanged(double)),
|
||||
this, SLOT(onOffsetChanged(double)));
|
||||
connect(ui->spinOffset2, SIGNAL(valueChanged(double)),
|
||||
this, SLOT(onOffset2Changed(double)));
|
||||
connect(ui->spinOffset3, SIGNAL(valueChanged(double)),
|
||||
this, SLOT(onOffset3Changed(double)));
|
||||
connect(ui->spinAngle, SIGNAL(valueChanged(double)),
|
||||
this, SLOT(onAngleChanged(double)));
|
||||
connect(ui->checkBoxFlip, SIGNAL(toggled(bool)),
|
||||
|
@ -129,6 +133,8 @@ TaskDatumParameters::TaskDatumParameters(ViewProviderDatum *DatumView,QWidget *p
|
|||
|
||||
// Temporarily prevent unnecessary feature recomputes
|
||||
ui->spinOffset->blockSignals(true);
|
||||
ui->spinOffset2->blockSignals(true);
|
||||
ui->spinOffset3->blockSignals(true);
|
||||
ui->spinAngle->blockSignals(true);
|
||||
ui->checkBoxFlip->blockSignals(true);
|
||||
ui->buttonRef1->blockSignals(true);
|
||||
|
@ -145,10 +151,14 @@ TaskDatumParameters::TaskDatumParameters(ViewProviderDatum *DatumView,QWidget *p
|
|||
|
||||
//bool checked1 = pcDatum->Checked.getValue();
|
||||
double offset = pcDatum->Offset.getValue();
|
||||
double offset2 = pcDatum->Offset2.getValue();
|
||||
double offset3 = pcDatum->Offset3.getValue();
|
||||
double angle = pcDatum->Angle.getValue();
|
||||
|
||||
// Fill data into dialog elements
|
||||
ui->spinOffset->setValue(offset);
|
||||
ui->spinOffset2->setValue(offset2);
|
||||
ui->spinOffset3->setValue(offset3);
|
||||
ui->spinAngle->setValue(angle);
|
||||
//ui->checkBoxFlip->setChecked(checked1);
|
||||
std::vector<QString> refstrings;
|
||||
|
@ -162,6 +172,8 @@ TaskDatumParameters::TaskDatumParameters(ViewProviderDatum *DatumView,QWidget *p
|
|||
|
||||
// activate and de-activate dialog elements as appropriate
|
||||
ui->spinOffset->blockSignals(false);
|
||||
ui->spinOffset2->blockSignals(false);
|
||||
ui->spinOffset3->blockSignals(false);
|
||||
ui->spinAngle->blockSignals(false);
|
||||
ui->checkBoxFlip->blockSignals(false);
|
||||
ui->buttonRef1->blockSignals(false);
|
||||
|
@ -198,11 +210,41 @@ const QString makeRefText(std::set<QString> hint)
|
|||
void TaskDatumParameters::updateUI()
|
||||
{
|
||||
ui->checkBoxFlip->setVisible(false);
|
||||
|
||||
int numOffsets = static_cast<Part::Datum*>(DatumView->getObject())->offsetsAllowed();
|
||||
if (numOffsets == 0) {
|
||||
ui->labelOffset->setVisible(false);
|
||||
ui->spinOffset->setVisible(false);
|
||||
ui->labelOffset2->setVisible(false);
|
||||
ui->spinOffset2->setVisible(false);
|
||||
ui->labelOffset3->setVisible(false);
|
||||
ui->spinOffset3->setVisible(false);
|
||||
} else if (numOffsets == 1) {
|
||||
ui->labelOffset->setVisible(true);
|
||||
ui->spinOffset->setVisible(true);
|
||||
ui->labelOffset2->setVisible(false);
|
||||
ui->spinOffset2->setVisible(false);
|
||||
ui->labelOffset3->setVisible(false);
|
||||
ui->spinOffset3->setVisible(false);
|
||||
} else if (numOffsets == 2) {
|
||||
ui->labelOffset->setVisible(true);
|
||||
ui->spinOffset->setVisible(true);
|
||||
ui->labelOffset2->setVisible(true);
|
||||
ui->spinOffset2->setVisible(true);
|
||||
ui->labelOffset3->setVisible(false);
|
||||
ui->spinOffset3->setVisible(false);
|
||||
} else if (numOffsets == 3) {
|
||||
ui->labelOffset->setVisible(true);
|
||||
ui->spinOffset->setVisible(true);
|
||||
ui->labelOffset2->setVisible(true);
|
||||
ui->spinOffset2->setVisible(true);
|
||||
ui->labelOffset3->setVisible(true);
|
||||
ui->spinOffset3->setVisible(true);
|
||||
}
|
||||
|
||||
if (DatumView->datumType != QObject::tr("Plane")) {
|
||||
ui->labelAngle->setVisible(false);
|
||||
ui->labelOffset->setVisible(false);
|
||||
ui->spinAngle->setVisible(false);
|
||||
ui->spinOffset->setVisible(false);
|
||||
}
|
||||
|
||||
Part::Datum* pcDatum = static_cast<Part::Datum*>(DatumView->getObject());
|
||||
|
@ -357,6 +399,22 @@ void TaskDatumParameters::onOffsetChanged(double val)
|
|||
updateUI();
|
||||
}
|
||||
|
||||
void TaskDatumParameters::onOffset2Changed(double val)
|
||||
{
|
||||
Part::Datum* pcDatum = static_cast<Part::Datum*>(DatumView->getObject());
|
||||
pcDatum->Offset2.setValue(val);
|
||||
pcDatum->getDocument()->recomputeFeature(pcDatum);
|
||||
updateUI();
|
||||
}
|
||||
|
||||
void TaskDatumParameters::onOffset3Changed(double val)
|
||||
{
|
||||
Part::Datum* pcDatum = static_cast<Part::Datum*>(DatumView->getObject());
|
||||
pcDatum->Offset3.setValue(val);
|
||||
pcDatum->getDocument()->recomputeFeature(pcDatum);
|
||||
updateUI();
|
||||
}
|
||||
|
||||
void TaskDatumParameters::onAngleChanged(double val)
|
||||
{
|
||||
Part::Datum* pcDatum = static_cast<Part::Datum*>(DatumView->getObject());
|
||||
|
@ -518,6 +576,16 @@ double TaskDatumParameters::getOffset() const
|
|||
return ui->spinOffset->value();
|
||||
}
|
||||
|
||||
double TaskDatumParameters::getOffset2() const
|
||||
{
|
||||
return ui->spinOffset2->value();
|
||||
}
|
||||
|
||||
double TaskDatumParameters::getOffset3() const
|
||||
{
|
||||
return ui->spinOffset3->value();
|
||||
}
|
||||
|
||||
double TaskDatumParameters::getAngle() const
|
||||
{
|
||||
return ui->spinAngle->value();
|
||||
|
@ -561,6 +629,8 @@ void TaskDatumParameters::changeEvent(QEvent *e)
|
|||
TaskBox::changeEvent(e);
|
||||
if (e->type() == QEvent::LanguageChange) {
|
||||
ui->spinOffset->blockSignals(true);
|
||||
ui->spinOffset2->blockSignals(true);
|
||||
ui->spinOffset3->blockSignals(true);
|
||||
ui->spinAngle->blockSignals(true);
|
||||
ui->checkBoxFlip->blockSignals(true);
|
||||
ui->buttonRef1->blockSignals(true);
|
||||
|
@ -580,6 +650,8 @@ void TaskDatumParameters::changeEvent(QEvent *e)
|
|||
// TODO: Translate DatumView->datumType ?
|
||||
|
||||
ui->spinOffset->blockSignals(false);
|
||||
ui->spinOffset2->blockSignals(false);
|
||||
ui->spinOffset3->blockSignals(false);
|
||||
ui->spinAngle->blockSignals(false);
|
||||
ui->checkBoxFlip->blockSignals(false);
|
||||
ui->buttonRef1->blockSignals(false);
|
||||
|
@ -634,6 +706,8 @@ bool TaskDlgDatumParameters::accept()
|
|||
|
||||
try {
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Offset = %f",name.c_str(),parameter->getOffset());
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Offset2 = %f",name.c_str(),parameter->getOffset2());
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Offset3 = %f",name.c_str(),parameter->getOffset3());
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Angle = %f",name.c_str(),parameter->getAngle());
|
||||
//Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Checked = %i",name.c_str(),parameter->getCheckBox1()?1:0);
|
||||
|
||||
|
|
|
@ -55,12 +55,16 @@ public:
|
|||
|
||||
QString getReference(const int idx) const;
|
||||
double getOffset(void) const;
|
||||
double getOffset2(void) const;
|
||||
double getOffset3(void) const;
|
||||
double getAngle(void) const;
|
||||
bool getFlip(void) const;
|
||||
const bool isCompleted() const { return completed; }
|
||||
|
||||
private Q_SLOTS:
|
||||
void onOffsetChanged(double);
|
||||
void onOffset2Changed(double);
|
||||
void onOffset3Changed(double);
|
||||
void onAngleChanged(double);
|
||||
void onCheckFlip(bool);
|
||||
void onRefName1(const QString& text);
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>272</width>
|
||||
<height>215</height>
|
||||
<height>285</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
|
@ -83,6 +83,60 @@
|
|||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<item>
|
||||
<widget class="QLabel" name="labelOffset2">
|
||||
<property name="text">
|
||||
<string>Offset</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="spinOffset2">
|
||||
<property name="minimum">
|
||||
<double>-999999999.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>999999999.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>5.000000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>0.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
||||
<item>
|
||||
<widget class="QLabel" name="labelOffset3">
|
||||
<property name="text">
|
||||
<string>Offset</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="spinOffset3">
|
||||
<property name="minimum">
|
||||
<double>-999999999.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>999999999.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>5.000000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>0.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
|
|
Loading…
Reference in New Issue
Block a user