+ 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:
parent
d03d74f6ae
commit
e2ce022839
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,7 +166,7 @@ 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())
|
||||
throw Base::Exception("Fusion with support failed");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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());
|
||||
Sketcher::SketchObject *pcSketch = static_cast<Sketcher::SketchObject*>(pcRevolution->Sketch.getValue());
|
||||
if (pcSketch) {
|
||||
int maxcount = pcSketch->getAxisCount()+2;
|
||||
if (num == 0)
|
||||
pcRevolution->Axis.setValue(Base::Vector3f(0,1,0));
|
||||
else
|
||||
pcRevolution->Axis.setValue(Base::Vector3f(1,0,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,15 +132,30 @@ double TaskRevolutionParameters::getAngle(void) const
|
|||
return ui->doubleSpinBox->value();
|
||||
}
|
||||
|
||||
Base::Vector3f TaskRevolutionParameters::getAxis(void) const
|
||||
QString TaskRevolutionParameters::getReferenceAxis(void) const
|
||||
{
|
||||
// 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)
|
||||
return Base::Vector3f(0,1,0);
|
||||
else
|
||||
return Base::Vector3f(1,0,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
|
||||
buf = QString::fromUtf8("''");
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
TaskRevolutionParameters::~TaskRevolutionParameters()
|
||||
{
|
||||
|
@ -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();
|
||||
|
|
|
@ -52,7 +52,7 @@ public:
|
|||
TaskRevolutionParameters(ViewProviderRevolution *RevolutionView,QWidget *parent = 0);
|
||||
~TaskRevolutionParameters();
|
||||
|
||||
Base::Vector3f getAxis (void) const;
|
||||
QString getReferenceAxis(void) const;
|
||||
double getAngle(void) const;
|
||||
|
||||
private Q_SLOTS:
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
@ -126,6 +122,11 @@ public:
|
|||
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
|
||||
virtual void onChanged(const App::Property* /*prop*/);
|
||||
|
|
Loading…
Reference in New Issue
Block a user