+ add axis link property to the PartDesign/Revolution feature

+ fix placement of the PartDesign/Revolution feature to the placement of its sketch/support


git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5279 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d
This commit is contained in:
logari81 2011-12-12 17:53:48 +00:00
parent d03d74f6ae
commit e2ce022839
12 changed files with 180 additions and 61 deletions

View File

@ -51,6 +51,8 @@
using namespace Part;
const int Part2DObject::H_Axis = -2;
const int Part2DObject::V_Axis = -3;
PROPERTY_SOURCE(Part::Part2DObject, Part::Feature)
@ -184,6 +186,16 @@ void Part2DObject::positionBySupport(void)
Placement.setValue(Base::Placement(mtrx));
}
int Part2DObject::getAxisCount(void) const
{
return 0;
}
Base::Axis Part2DObject::getAxis(int axId) const
{
return Base::Axis();
}
bool Part2DObject::seekTrimPoints(const std::vector<Geometry *> &geomlist,
int GeoId, const Base::Vector3d &point,
int &GeoId1, Base::Vector3d &intersect1,

View File

@ -26,6 +26,7 @@
#define PART_PART2DOBJECT_H
#include <App/PropertyStandard.h>
#include <Base/Axis.h>
#include "PartFeature.h"
@ -68,6 +69,11 @@ public:
*/
void positionBySupport(void);
/// returns the number of construction lines (to be used as axes)
virtual int getAxisCount(void) const;
/// retrieves an axis iterating through the construction lines of the sketch (indices start at 0)
virtual Base::Axis getAxis(int axId) const;
/** calculate the points where a curve with index GeoId should be trimmed
* with respect to the rest of the curves contained in the list geomlist
* and a picked point. The outputs intersect1 and intersect2 specify the
@ -80,6 +86,9 @@ public:
int &GeoId1, Base::Vector3d &intersect1,
int &GeoId2, Base::Vector3d &intersect2);
static const int H_Axis;
static const int V_Axis;
/** @name methods overide Feature */
//@{
/// recalculate the Feature

View File

@ -35,6 +35,7 @@
# include <BRepAlgoAPI_Fuse.hxx>
#endif
#include <Base/Axis.h>
#include <Base/Placement.h>
#include <Base/Tools.h>
#include <Mod/Part/App/Part2DObject.h>
@ -54,11 +55,14 @@ Revolution::Revolution()
ADD_PROPERTY(Base,(Base::Vector3f(0.0f,0.0f,0.0f)));
ADD_PROPERTY(Axis,(Base::Vector3f(0.0f,1.0f,0.0f)));
ADD_PROPERTY(Angle,(360.0));
ADD_PROPERTY_TYPE(ReferenceAxis,(0),"Revolution",(App::PropertyType)(App::Prop_None),"Reference axis of revolution");
}
short Revolution::mustExecute() const
{
if (Sketch.isTouched() ||
if (Placement.isTouched() ||
Sketch.isTouched() ||
ReferenceAxis.isTouched() ||
Axis.isTouched() ||
Base.isTouched() ||
Angle.isTouched())
@ -73,7 +77,10 @@ App::DocumentObjectExecReturn *Revolution::execute(void)
return new App::DocumentObjectExecReturn("No sketch linked");
if (!link->getTypeId().isDerivedFrom(Part::Part2DObject::getClassTypeId()))
return new App::DocumentObjectExecReturn("Linked object is not a Sketch or Part2DObject");
TopoDS_Shape shape = static_cast<Part::Part2DObject*>(link)->Shape.getShape()._Shape;
Part::Part2DObject* pcSketch=static_cast<Part::Part2DObject*>(link);
TopoDS_Shape shape = pcSketch->Shape.getShape()._Shape;
if (shape.IsNull())
return new App::DocumentObjectExecReturn("Linked shape object is empty");
@ -94,40 +101,63 @@ App::DocumentObjectExecReturn *Revolution::execute(void)
}
if (wires.empty()) // there can be several wires
return new App::DocumentObjectExecReturn("Linked shape object is not a wire");
#if 0
App::DocumentObject* support = sketch->Support.getValue();
Base::Placement placement = sketch->Placement.getValue();
Base::Vector3d axis(0,1,0);
placement.getRotation().multVec(axis, axis);
Base::BoundBox3d bbox = sketch->Shape.getBoundingBox();
bbox.Enlarge(0.1);
Base::Vector3d base(bbox.MaxX, bbox.MaxY, bbox.MaxZ);
#endif
// get the Sketch plane
Base::Placement SketchPos = static_cast<Part::Part2DObject*>(link)->Placement.getValue();
Base::Rotation SketchOrientation = SketchPos.getRotation();
// get rvolve axis
Base::Vector3f v = Axis.getValue();
Base::Vector3d SketchOrientationVector(v.x,v.y,v.z);
SketchOrientation.multVec(SketchOrientationVector,SketchOrientationVector);
Base::Placement SketchPlm = pcSketch->Placement.getValue();
// get reference axis
App::DocumentObject *pcReferenceAxis = ReferenceAxis.getValue();
const std::vector<std::string> &subReferenceAxis = ReferenceAxis.getSubValues();
if (pcReferenceAxis && pcReferenceAxis == pcSketch) {
bool hasValidAxis=false;
Base::Axis axis;
if (subReferenceAxis[0] == "V_Axis") {
hasValidAxis = true;
axis = pcSketch->getAxis(Part::Part2DObject::V_Axis);
}
else if (subReferenceAxis[0] == "H_Axis") {
hasValidAxis = true;
axis = pcSketch->getAxis(Part::Part2DObject::H_Axis);
}
else if (subReferenceAxis[0].size() > 4 && subReferenceAxis[0].substr(0,4) == "Axis") {
int AxId = std::atoi(subReferenceAxis[0].substr(4,4000).c_str());
if (AxId >= 0 && AxId < pcSketch->getAxisCount()) {
hasValidAxis = true;
axis = pcSketch->getAxis(AxId);
}
}
if (hasValidAxis) {
axis *= SketchPlm;
Base::Vector3d base=axis.getBase();
Base::Vector3d dir=axis.getDirection();
Base.setValue(base.x,base.y,base.z);
Axis.setValue(dir.x,dir.y,dir.z);
}
}
// get revolve axis
Base::Vector3f b = Base.getValue();
gp_Pnt pnt(b.x,b.y,b.z);
gp_Dir dir(SketchOrientationVector.x,SketchOrientationVector.y,SketchOrientationVector.z);
Base::Vector3f v = Axis.getValue();
gp_Dir dir(v.x,v.y,v.z);
// get the support of the Sketch if any
App::DocumentObject* SupportLink = static_cast<Part::Part2DObject*>(link)->Support.getValue();
App::DocumentObject* pcSupport = pcSketch->Support.getValue();
Part::Feature *SupportObject = 0;
if (SupportLink && SupportLink->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()))
SupportObject = static_cast<Part::Feature*>(SupportLink);
if (pcSupport && pcSupport->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()))
SupportObject = static_cast<Part::Feature*>(pcSupport);
TopoDS_Shape aFace = makeFace(wires);
if (aFace.IsNull())
return new App::DocumentObjectExecReturn("Creating a face from sketch failed");
this->positionBySketch();
TopLoc_Location invObjLoc = this->getLocation().Inverted();
pnt.Transform(invObjLoc.Transformation());
dir.Transform(invObjLoc.Transformation());
// revolve the face to a solid
BRepPrimAPI_MakeRevol RevolMaker(aFace,gp_Ax1(pnt, dir), Base::toRadians<double>(Angle.getValue()));
BRepPrimAPI_MakeRevol RevolMaker(aFace.Moved(invObjLoc), gp_Ax1(pnt, dir), Base::toRadians<double>(Angle.getValue()));
if (RevolMaker.IsDone()) {
TopoDS_Shape result = RevolMaker.Shape();
@ -136,9 +166,9 @@ App::DocumentObjectExecReturn *Revolution::execute(void)
const TopoDS_Shape& support = SupportObject->Shape.getValue();
if (!support.IsNull() && support.ShapeType() == TopAbs_SOLID) {
// Let's call algorithm computing a fuse operation:
BRepAlgoAPI_Fuse mkFuse(support, result);
BRepAlgoAPI_Fuse mkFuse(support.Moved(invObjLoc), result);
// Let's check if the fusion has been successful
if (!mkFuse.IsDone())
if (!mkFuse.IsDone())
throw Base::Exception("Fusion with support failed");
result = mkFuse.Shape();
}

View File

@ -41,6 +41,11 @@ public:
App::PropertyVector Axis;
App::PropertyAngle Angle;
/** if this property is set to a valid link, both Axis and Base properties
* are calculated according to the linked line
*/
App::PropertyLinkSub ReferenceAxis;
/** @name methods override feature */
//@{
/// recalculate the feature

View File

@ -51,7 +51,6 @@
#include "FeatureSketchBased.h"
#include <Mod/Part/App/Part2DObject.h>
using namespace PartDesign;
namespace PartDesign {
@ -256,4 +255,10 @@ TopoDS_Shape SketchBased::makeFace(const std::vector<TopoDS_Wire>& w) const
}
}
int SketchBased::getSketchAxisCount(void) const
{
Part::Part2DObject *sketch = static_cast<Part::Part2DObject*>(Sketch.getValue());
return sketch->getAxisCount();
}
}

View File

@ -47,6 +47,9 @@ public:
*/
void positionBySketch(void);
/// retrieves the number of axes in the linked sketch (defined as construction lines)
int getSketchAxisCount(void) const;
protected:
TopoDS_Face validateFace(const TopoDS_Face&) const;
TopoDS_Shape makeFace(const std::vector<TopoDS_Wire>&) const;

View File

@ -48,7 +48,7 @@ using namespace std;
//DEF_STD_CMD_A(CmdPartDesignNewSketch);
//
//CmdPartDesignNewSketch::CmdPartDesignNewSketch()
// :Command("PartDesign_NewSketch")
// :Command("PartDesign_NewSketch")
//{
// sAppModule = "PartDesign";
// sGroup = QT_TR_NOOP("PartDesign");
@ -72,7 +72,7 @@ using namespace std;
// doCommand(Doc,"App.activeDocument().addObject('Sketcher::SketchObject','%s')",FeatName.c_str());
// doCommand(Gui,"Gui.activeDocument().activeView().setCamera('%s')",cam.c_str());
// doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str());
//
//
// //getDocument()->recompute();
//}
//
@ -293,7 +293,8 @@ void CmdPartDesignRevolution::activated(int iMsg)
openCommand("Make Revolution");
doCommand(Doc,"App.activeDocument().addObject(\"PartDesign::Revolution\",\"%s\")",FeatName.c_str());
doCommand(Doc,"App.activeDocument().%s.Sketch = App.activeDocument().%s",FeatName.c_str(),sketch->getNameInDocument());
doCommand(Doc,"App.activeDocument().%s.Axis = App.Vector(0,1,0)",FeatName.c_str());
doCommand(Doc,"App.activeDocument().%s.ReferenceAxis = (App.activeDocument().%s,['V_Axis'])",
FeatName.c_str(), sketch->getNameInDocument());
doCommand(Doc,"App.activeDocument().%s.Angle = 360.0",FeatName.c_str());
updateActive();
if (isActiveObjectValid()) {

View File

@ -65,15 +65,37 @@ TaskRevolutionParameters::TaskRevolutionParameters(ViewProviderRevolution *Revol
PartDesign::Revolution* pcRevolution = static_cast<PartDesign::Revolution*>(RevolutionView->getObject());
double l = pcRevolution->Angle.getValue();
Base::Vector3f Ax = pcRevolution->Axis.getValue();
ui->doubleSpinBox->setValue(l);
ui->doubleSpinBox->selectAll();
QMetaObject::invokeMethod(ui->doubleSpinBox, "setFocus", Qt::QueuedConnection);
if (Ax.y > 0)
ui->axis->setCurrentIndex(0);
else
ui->axis->setCurrentIndex(1);
int count=pcRevolution->getSketchAxisCount();
for (int i=ui->axis->count()-1; i >= count+2; i--)
ui->axis->removeItem(i);
for (int i=ui->axis->count(); i < count+2; i++)
ui->axis->addItem(QString::fromAscii("Sketch axis %1").arg(i-2));
int pos=-1;
App::DocumentObject *pcReferenceAxis = pcRevolution->ReferenceAxis.getValue();
const std::vector<std::string> &subReferenceAxis = pcRevolution->ReferenceAxis.getSubValues();
if (pcReferenceAxis && pcReferenceAxis == pcRevolution->Sketch.getValue()) {
assert(subReferenceAxis.size()==1);
if (subReferenceAxis[0] == "V_Axis")
pos = 0;
else if (subReferenceAxis[0] == "H_Axis")
pos = 1;
else if (subReferenceAxis[0].size() > 4 && subReferenceAxis[0].substr(0,4) == "Axis")
pos = 2 + std::atoi(subReferenceAxis[0].substr(4,4000).c_str());
}
if (pos < 0 || pos >= ui->axis->count()) {
ui->axis->addItem(QString::fromAscii("Undefined"));
pos = ui->axis->count()-1;
}
ui->axis->setCurrentIndex(pos);
setFocus ();
}
void TaskRevolutionParameters::onAngleChanged(double len)
@ -86,11 +108,21 @@ void TaskRevolutionParameters::onAngleChanged(double len)
void TaskRevolutionParameters::onAxisChanged(int num)
{
PartDesign::Revolution* pcRevolution = static_cast<PartDesign::Revolution*>(RevolutionView->getObject());
if(num == 0)
pcRevolution->Axis.setValue(Base::Vector3f(0,1,0));
else
pcRevolution->Axis.setValue(Base::Vector3f(1,0,0));
Sketcher::SketchObject *pcSketch = static_cast<Sketcher::SketchObject*>(pcRevolution->Sketch.getValue());
if (pcSketch) {
int maxcount = pcSketch->getAxisCount()+2;
if (num == 0)
pcRevolution->ReferenceAxis.setValue(pcSketch, std::vector<std::string>(1,"V_Axis"));
else if (num == 1)
pcRevolution->ReferenceAxis.setValue(pcSketch, std::vector<std::string>(1,"H_Axis"));
else if (num >= 2 && num < maxcount) {
QString buf = QString::fromUtf8("Axis%1").arg(num-2);
std::string str = buf.toStdString();
pcRevolution->ReferenceAxis.setValue(pcSketch, std::vector<std::string>(1,str));
}
if (num < maxcount && ui->axis->count() > maxcount)
ui->axis->setMaxCount(maxcount);
}
pcRevolution->getDocument()->recomputeFeature(pcRevolution);
}
@ -100,16 +132,31 @@ double TaskRevolutionParameters::getAngle(void) const
return ui->doubleSpinBox->value();
}
Base::Vector3f TaskRevolutionParameters::getAxis(void) const
QString TaskRevolutionParameters::getReferenceAxis(void) const
{
if( ui->axis->currentIndex() == 0)
return Base::Vector3f(0,1,0);
// get the support and Sketch
PartDesign::Revolution* pcRevolution = static_cast<PartDesign::Revolution*>(RevolutionView->getObject());
Sketcher::SketchObject *pcSketch = static_cast<Sketcher::SketchObject*>(pcRevolution->Sketch.getValue());
QString buf;
if (pcSketch) {
buf = QString::fromUtf8("(App.ActiveDocument.%1,[%2])");
buf = buf.arg(QString::fromUtf8(pcSketch->getNameInDocument()));
if (ui->axis->currentIndex() == 0)
buf = buf.arg(QString::fromUtf8("'V_Axis'"));
else if (ui->axis->currentIndex() == 1)
buf = buf.arg(QString::fromUtf8("'H_Axis'"));
else if (ui->axis->currentIndex() >= 2) {
buf = buf.arg(QString::fromUtf8("'Axis%1'"));
buf = buf.arg(ui->axis->currentIndex()-2);
}
}
else
return Base::Vector3f(1,0,0);
buf = QString::fromUtf8("''");
return buf;
}
TaskRevolutionParameters::~TaskRevolutionParameters()
{
delete ui;
@ -147,12 +194,12 @@ TaskDlgRevolutionParameters::~TaskDlgRevolutionParameters()
void TaskDlgRevolutionParameters::open()
{
}
void TaskDlgRevolutionParameters::clicked(int)
{
}
bool TaskDlgRevolutionParameters::accept()
@ -161,8 +208,8 @@ bool TaskDlgRevolutionParameters::accept()
//Gui::Command::openCommand("Revolution changed");
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Angle = %f",name.c_str(),parameter->getAngle());
Base::Vector3f axis = parameter->getAxis();
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Axis = FreeCAD.Vector(%f,%f,%f)",name.c_str(),axis.x,axis.y,axis.z);
std::string axis = parameter->getReferenceAxis().toStdString();
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.ReferenceAxis = %s",name.c_str(),axis.c_str());
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()");
Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()");
Gui::Command::commitCommand();
@ -173,18 +220,18 @@ bool TaskDlgRevolutionParameters::accept()
bool TaskDlgRevolutionParameters::reject()
{
// get the support and Sketch
PartDesign::Revolution* pcRevolution = static_cast<PartDesign::Revolution*>(RevolutionView->getObject());
PartDesign::Revolution* pcRevolution = static_cast<PartDesign::Revolution*>(RevolutionView->getObject());
Sketcher::SketchObject *pcSketch;
App::DocumentObject *pcSupport;
if (pcRevolution->Sketch.getValue()) {
pcSketch = static_cast<Sketcher::SketchObject*>(pcRevolution->Sketch.getValue());
pcSketch = static_cast<Sketcher::SketchObject*>(pcRevolution->Sketch.getValue());
pcSupport = pcSketch->Support.getValue();
}
// role back the done things
Gui::Command::abortCommand();
Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()");
// if abort command deleted the object the support is visible again
if (!Gui::Application::Instance->getViewProvider(pcRevolution)) {
if (pcSketch && Gui::Application::Instance->getViewProvider(pcSketch))

View File

@ -52,8 +52,8 @@ public:
TaskRevolutionParameters(ViewProviderRevolution *RevolutionView,QWidget *parent = 0);
~TaskRevolutionParameters();
Base::Vector3f getAxis (void) const;
double getAngle(void) const;
QString getReferenceAxis(void) const;
double getAngle(void) const;
private Q_SLOTS:
void onAngleChanged(double);

View File

@ -27,12 +27,12 @@
<widget class="QComboBox" name="axis">
<item>
<property name="text">
<string>Vertical</string>
<string>Vertical sketch axis</string>
</property>
</item>
<item>
<property name="text">
<string>Horizontal</string>
<string>Horizontal sketch axis</string>
</property>
</item>
</widget>

View File

@ -222,6 +222,12 @@ int SketchObject::getAxisCount(void) const
Base::Axis SketchObject::getAxis(int axId) const
{
const std::vector< Part::Geometry * > &vals = this->Geometry.getValues();
if (axId == H_Axis) {
return Base::Axis(Base::Vector3d(0,0,0), Base::Vector3d(1,0,0));
}
else if (axId == V_Axis) {
return Base::Axis(Base::Vector3d(0,0,0), Base::Vector3d(0,1,0));
}
int count=0;
for (std::vector<Part::Geometry *>::const_iterator geo=vals.begin();

View File

@ -89,10 +89,6 @@ public:
int movePoint(int geoIndex1, PointPos Pos1, const Base::Vector3d& toPoint, bool relative=false);
/// retrieves the coordinates of a point
Base::Vector3d getPoint(int geoIndex1, PointPos Pos1);
/// returns the number of construction lines (to be used as axes)
int getAxisCount(void) const;
/// retrieves an axis iterating through the construction lines of the sketch (indices start at 0)
Base::Axis getAxis(int axId) const;
/// toggle geometry to draft line
int toggleConstruction(int GeoNbr);
@ -125,6 +121,11 @@ public:
virtual unsigned int getMemSize(void) const;
virtual void Save(Base::Writer &/*writer*/) const;
virtual void Restore(Base::XMLReader &/*reader*/);
/// returns the number of construction lines (to be used as axes)
virtual int getAxisCount(void) const;
/// retrieves an axis iterating through the construction lines of the sketch (indices start at 0)
virtual Base::Axis getAxis(int axId) const;
protected:
/// get called by the container when a property has changed